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), |