diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 38 | 
1 files changed, 22 insertions, 16 deletions
| diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7eed331e90f0..55c78c318ccd 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3177,6 +3177,23 @@ static bool has_cap_mac_admin(bool audit)  	return true;  } +/** + * selinux_inode_xattr_skipcap - Skip the xattr capability checks? + * @name: name of the xattr + * + * Returns 1 to indicate that SELinux "owns" the access control rights to xattrs + * named @name; the LSM layer should avoid enforcing any traditional + * capability based access controls on this xattr.  Returns 0 to indicate that + * SELinux does not "own" the access control rights to xattrs named @name and is + * deferring to the LSM layer for further access controls, including capability + * based controls. + */ +static int selinux_inode_xattr_skipcap(const char *name) +{ +	/* require capability check if not a selinux xattr */ +	return !strcmp(name, XATTR_NAME_SELINUX); +} +  static int selinux_inode_setxattr(struct mnt_idmap *idmap,  				  struct dentry *dentry, const char *name,  				  const void *value, size_t size, int flags) @@ -3188,15 +3205,9 @@ static int selinux_inode_setxattr(struct mnt_idmap *idmap,  	u32 newsid, sid = current_sid();  	int rc = 0; -	if (strcmp(name, XATTR_NAME_SELINUX)) { -		rc = cap_inode_setxattr(dentry, name, value, size, flags); -		if (rc) -			return rc; - -		/* Not an attribute we recognize, so just check the -		   ordinary setattr permission. */ +	/* if not a selinux xattr, only check the ordinary setattr perm */ +	if (strcmp(name, XATTR_NAME_SELINUX))  		return dentry_has_perm(current_cred(), dentry, FILE__SETATTR); -	}  	if (!selinux_initialized())  		return (inode_owner_or_capable(idmap, inode) ? 0 : -EPERM); @@ -3345,15 +3356,9 @@ static int selinux_inode_listxattr(struct dentry *dentry)  static int selinux_inode_removexattr(struct mnt_idmap *idmap,  				     struct dentry *dentry, const char *name)  { -	if (strcmp(name, XATTR_NAME_SELINUX)) { -		int rc = cap_inode_removexattr(idmap, dentry, name); -		if (rc) -			return rc; - -		/* Not an attribute we recognize, so just check the -		   ordinary setattr permission. */ +	/* if not a selinux xattr, only check the ordinary setattr perm */ +	if (strcmp(name, XATTR_NAME_SELINUX))  		return dentry_has_perm(current_cred(), dentry, FILE__SETATTR); -	}  	if (!selinux_initialized())  		return 0; @@ -7175,6 +7180,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {  	LSM_HOOK_INIT(inode_permission, selinux_inode_permission),  	LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),  	LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr), +	LSM_HOOK_INIT(inode_xattr_skipcap, selinux_inode_xattr_skipcap),  	LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),  	LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),  	LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr), |