You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
xattr: Add __vfs_{get,set,remove}xattr helpers
Right now, various places in the kernel check for the existence of getxattr, setxattr, and removexattr inode operations and directly call those operations. Switch to helper functions and test for the IOP_XATTR flag instead. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Acked-by: James Morris <james.l.morris@oracle.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
committed by
Al Viro
parent
f5c2443837
commit
5d6c31910b
+10
-15
@@ -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);
|
||||
int error;
|
||||
|
||||
if (!inode->i_op->removexattr)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
ssize_t ret;
|
||||
|
||||
if (!inode->i_op->getxattr)
|
||||
return 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user