]> Git Repo - linux.git/blobdiff - security/selinux/hooks.c
perf annotate: Start supporting cross arch annotation
[linux.git] / security / selinux / hooks.c
index a2d510895ff3fc19e9cd67ef79d2f2a9e8f16e57..085057936287bdaa559e7c4be9e593e17ec1dfa9 100644 (file)
@@ -507,14 +507,14 @@ static int sb_finish_set_opts(struct super_block *sb)
                   the root directory.  -ENODATA is ok, as this may be
                   the first boot of the SELinux kernel before we have
                   assigned xattr values to the filesystem. */
-               if (!root_inode->i_op->getxattr) {
+               if (!(root_inode->i_opflags & IOP_XATTR)) {
                        printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
                               "xattr support\n", sb->s_id, sb->s_type->name);
                        rc = -EOPNOTSUPP;
                        goto out;
                }
-               rc = root_inode->i_op->getxattr(root, root_inode,
-                                               XATTR_NAME_SELINUX, NULL, 0);
+
+               rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
                if (rc < 0 && rc != -ENODATA) {
                        if (rc == -EOPNOTSUPP)
                                printk(KERN_WARNING "SELinux: (dev %s, type "
@@ -1410,11 +1410,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
        case SECURITY_FS_USE_NATIVE:
                break;
        case SECURITY_FS_USE_XATTR:
-               if (!inode->i_op->getxattr) {
+               if (!(inode->i_opflags & IOP_XATTR)) {
                        isec->sid = sbsec->def_sid;
                        break;
                }
-
                /* Need a dentry, since the xattr API requires one.
                   Life would be simpler if we could just pass the inode. */
                if (opt_dentry) {
@@ -1445,14 +1444,12 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                        goto out_unlock;
                }
                context[len] = '\0';
-               rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX,
-                                          context, len);
+               rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
                if (rc == -ERANGE) {
                        kfree(context);
 
                        /* Need a larger buffer.  Query for the right size. */
-                       rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX,
-                                                  NULL, 0);
+                       rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
                        if (rc < 0) {
                                dput(dentry);
                                goto out_unlock;
@@ -1465,9 +1462,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                                goto out_unlock;
                        }
                        context[len] = '\0';
-                       rc = inode->i_op->getxattr(dentry, inode,
-                                                  XATTR_NAME_SELINUX,
-                                                  context, len);
+                       rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
                }
                dput(dentry);
                if (rc < 0) {
@@ -1761,8 +1756,8 @@ static inline int file_path_has_perm(const struct cred *cred,
 {
        struct common_audit_data ad;
 
-       ad.type = LSM_AUDIT_DATA_PATH;
-       ad.u.path = file->f_path;
+       ad.type = LSM_AUDIT_DATA_FILE;
+       ad.u.file = file;
        return inode_has_perm(cred, file_inode(file), av, &ad);
 }
 
@@ -1784,8 +1779,8 @@ static int file_has_perm(const struct cred *cred,
        u32 sid = cred_sid(cred);
        int rc;
 
-       ad.type = LSM_AUDIT_DATA_PATH;
-       ad.u.path = file->f_path;
+       ad.type = LSM_AUDIT_DATA_FILE;
+       ad.u.file = file;
 
        if (sid != fsec->sid) {
                rc = avc_has_perm(sid, fsec->sid,
@@ -1808,13 +1803,13 @@ out:
 /*
  * Determine the label for an inode that might be unioned.
  */
-static int selinux_determine_inode_label(struct inode *dir,
-                                        const struct qstr *name,
-                                        u16 tclass,
-                                        u32 *_new_isid)
+static int
+selinux_determine_inode_label(const struct task_security_struct *tsec,
+                                struct inode *dir,
+                                const struct qstr *name, u16 tclass,
+                                u32 *_new_isid)
 {
        const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
-       const struct task_security_struct *tsec = current_security();
 
        if ((sbsec->flags & SE_SBINITIALIZED) &&
            (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
@@ -1857,8 +1852,8 @@ static int may_create(struct inode *dir,
        if (rc)
                return rc;
 
-       rc = selinux_determine_inode_label(dir, &dentry->d_name, tclass,
-                                          &newsid);
+       rc = selinux_determine_inode_label(current_security(), dir,
+                                          &dentry->d_name, tclass, &newsid);
        if (rc)
                return rc;
 
@@ -2365,8 +2360,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
                        new_tsec->sid = old_tsec->sid;
        }
 
-       ad.type = LSM_AUDIT_DATA_PATH;
-       ad.u.path = bprm->file->f_path;
+       ad.type = LSM_AUDIT_DATA_FILE;
+       ad.u.file = bprm->file;
 
        if (new_tsec->sid == old_tsec->sid) {
                rc = avc_has_perm(old_tsec->sid, isec->sid,
@@ -2838,7 +2833,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
        u32 newsid;
        int rc;
 
-       rc = selinux_determine_inode_label(d_inode(dentry->d_parent), name,
+       rc = selinux_determine_inode_label(current_security(),
+                                          d_inode(dentry->d_parent), name,
                                           inode_mode_to_security_class(mode),
                                           &newsid);
        if (rc)
@@ -2847,6 +2843,27 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
        return security_sid_to_context(newsid, (char **)ctx, ctxlen);
 }
 
+static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
+                                         struct qstr *name,
+                                         const struct cred *old,
+                                         struct cred *new)
+{
+       u32 newsid;
+       int rc;
+       struct task_security_struct *tsec;
+
+       rc = selinux_determine_inode_label(old->security,
+                                          d_inode(dentry->d_parent), name,
+                                          inode_mode_to_security_class(mode),
+                                          &newsid);
+       if (rc)
+               return rc;
+
+       tsec = new->security;
+       tsec->create_sid = newsid;
+       return 0;
+}
+
 static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
                                       const struct qstr *qstr,
                                       const char **name,
@@ -2863,7 +2880,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
        sid = tsec->sid;
        newsid = tsec->create_sid;
 
-       rc = selinux_determine_inode_label(
+       rc = selinux_determine_inode_label(current_security(),
                dir, qstr,
                inode_mode_to_security_class(inode->i_mode),
                &newsid);
@@ -3811,8 +3828,8 @@ static int selinux_kernel_module_from_file(struct file *file)
 
        /* finit_module */
 
-       ad.type = LSM_AUDIT_DATA_PATH;
-       ad.u.path = file->f_path;
+       ad.type = LSM_AUDIT_DATA_FILE;
+       ad.u.file = file;
 
        fsec = file->f_security;
        if (sid != fsec->sid) {
@@ -6097,6 +6114,7 @@ static struct security_hook_list selinux_hooks[] = {
        LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str),
 
        LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
+       LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
 
        LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
        LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
This page took 0.041619 seconds and 4 git commands to generate.