diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 17:11:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 17:11:50 -0700 |
commit | 97d2116708ca0fd6ad8b00811ee4349b7e19e96f (patch) | |
tree | 81f73fc1a6daee60737b591cf1be73cc4f79de37 /security | |
parent | 30066ce675d3af350bc5a53858991c0b518dda00 (diff) | |
parent | fd50ecaddf8372a1d96e0daeaac0f93cf04e4d42 (diff) | |
download | lwn-97d2116708ca0fd6ad8b00811ee4349b7e19e96f.tar.gz lwn-97d2116708ca0fd6ad8b00811ee4349b7e19e96f.zip |
Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr updates from Al Viro:
"xattr stuff from Andreas
This completes the switch to xattr_handler ->get()/->set() from
->getxattr/->setxattr/->removexattr"
* 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: Remove {get,set,remove}xattr inode operations
xattr: Stop calling {get,set,remove}xattr inode operations
vfs: Check for the IOP_XATTR flag in listxattr
xattr: Add __vfs_{get,set,remove}xattr helpers
libfs: Use IOP_XATTR flag for empty directory handling
vfs: Use IOP_XATTR flag for bad-inode handling
vfs: Add IOP_XATTR inode operations flag
vfs: Move xattr_resolve_name to the front of fs/xattr.c
ecryptfs: Switch to generic xattr handlers
sockfs: Get rid of getxattr iop
sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
kernfs: Switch to generic xattr handlers
hfs: Switch to generic xattr handlers
jffs2: Remove jffs2_{get,set,remove}xattr macros
xattr: Remove unnecessary NULL attribute name check
Diffstat (limited to 'security')
-rw-r--r-- | security/commoncap.c | 25 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 7 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 21 | ||||
-rw-r--r-- | security/selinux/hooks.c | 19 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 12 |
6 files changed, 39 insertions, 49 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 14540bd78561..8df676fbd393 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -310,13 +310,8 @@ int cap_inode_need_killpriv(struct dentry *dentry) struct inode *inode = d_backing_inode(dentry); int error; - if (!inode->i_op->getxattr) - return 0; - - error = inode->i_op->getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0); - if (error <= 0) - return 0; - return 1; + error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0); + return error > 0; } /** @@ -329,12 +324,12 @@ int cap_inode_need_killpriv(struct dentry *dentry) */ int cap_inode_killpriv(struct dentry *dentry) { - struct inode *inode = d_backing_inode(dentry); - - if (!inode->i_op->removexattr) - return 0; + int error; - return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS); + error = __vfs_removexattr(dentry, XATTR_NAME_CAPS); + if (error == -EOPNOTSUPP) + error = 0; + return error; } /* @@ -394,11 +389,11 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data)); - if (!inode || !inode->i_op->getxattr) + if (!inode) return -ENODATA; - size = inode->i_op->getxattr((struct dentry *)dentry, inode, - XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ); + size = __vfs_getxattr((struct dentry *)dentry, inode, + XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ); if (size == -ENODATA || size == -EOPNOTSUPP) /* no data, that's ok */ return -ENODATA; diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 11c1d30bd705..bf663915412e 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -182,8 +182,9 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, int error; int size; - if (!inode->i_op->getxattr) + if (!(inode->i_opflags & IOP_XATTR)) return -EOPNOTSUPP; + desc = init_desc(type); if (IS_ERR(desc)) return PTR_ERR(desc); @@ -253,8 +254,8 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, &xattr_data, sizeof(xattr_data), 0); - } else if (rc == -ENODATA && inode->i_op->removexattr) { - rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); + } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) { + rc = __vfs_removexattr(dentry, XATTR_NAME_EVM); } return rc; } diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index b9e26288d30c..ba8615576d4d 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -78,11 +78,11 @@ static int evm_find_protected_xattrs(struct dentry *dentry) int error; int count = 0; - if (!inode->i_op->getxattr) + if (!(inode->i_opflags & IOP_XATTR)) return -EOPNOTSUPP; for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { - error = inode->i_op->getxattr(dentry, inode, *xattr, NULL, 0); + error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0); if (error < 0) { if (error == -ENODATA) continue; diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index ef1e4e701780..389325ac6067 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -165,13 +165,13 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int ima_read_xattr(struct dentry *dentry, struct evm_ima_xattr_data **xattr_value) { - struct inode *inode = d_backing_inode(dentry); - - if (!inode->i_op->getxattr) - return 0; + ssize_t ret; - return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value, - 0, GFP_NOFS); + ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value, + 0, GFP_NOFS); + if (ret == -EOPNOTSUPP) + ret = 0; + return ret; } /* @@ -195,7 +195,7 @@ int ima_appraise_measurement(enum ima_hooks func, enum integrity_status status = INTEGRITY_UNKNOWN; int rc = xattr_len, hash_start = 0; - if (!inode->i_op->getxattr) + if (!(inode->i_opflags & IOP_XATTR)) return INTEGRITY_UNKNOWN; if (rc <= 0) { @@ -322,10 +322,10 @@ void ima_inode_post_setattr(struct dentry *dentry) { struct inode *inode = d_backing_inode(dentry); struct integrity_iint_cache *iint; - int must_appraise, rc; + int must_appraise; if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode) - || !inode->i_op->removexattr) + || !(inode->i_opflags & IOP_XATTR)) return; must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR); @@ -338,8 +338,7 @@ void ima_inode_post_setattr(struct dentry *dentry) iint->flags |= IMA_APPRAISE; } if (!must_appraise) - rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA); - return; + __vfs_removexattr(dentry, XATTR_NAME_IMA); } /* diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2205ea27aa0a..085057936287 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -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) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index caec2256ab22..1cb060293505 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -265,14 +265,14 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, char *buffer; struct smack_known *skp = NULL; - if (ip->i_op->getxattr == NULL) + if (!(ip->i_opflags & IOP_XATTR)) return ERR_PTR(-EOPNOTSUPP); buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); if (buffer == NULL) return ERR_PTR(-ENOMEM); - rc = ip->i_op->getxattr(dp, ip, name, buffer, SMK_LONGLABEL); + rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL); if (rc < 0) skp = ERR_PTR(rc); else if (rc == 0) @@ -3520,8 +3520,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * It would be curious if the label of the task * does not match that assigned. */ - if (inode->i_op->getxattr == NULL) - break; + if (!(inode->i_opflags & IOP_XATTR)) + break; /* * Get the dentry for xattr. */ @@ -3545,12 +3545,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ if (isp->smk_flags & SMK_INODE_CHANGED) { isp->smk_flags &= ~SMK_INODE_CHANGED; - rc = inode->i_op->setxattr(dp, inode, + rc = __vfs_setxattr(dp, inode, XATTR_NAME_SMACKTRANSMUTE, TRANS_TRUE, TRANS_TRUE_SIZE, 0); } else { - rc = inode->i_op->getxattr(dp, inode, + rc = __vfs_getxattr(dp, inode, XATTR_NAME_SMACKTRANSMUTE, trattr, TRANS_TRUE_SIZE); if (rc >= 0 && strncmp(trattr, TRANS_TRUE, |