summaryrefslogtreecommitdiff
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c38
-rw-r--r--security/selinux/include/audit.h4
-rw-r--r--security/selinux/ss/ebitmap.h2
-rw-r--r--security/selinux/ss/services.c5
4 files changed, 29 insertions, 20 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),
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
index 52aca71210b4..29c7d4c86f6d 100644
--- a/security/selinux/include/audit.h
+++ b/security/selinux/include/audit.h
@@ -21,12 +21,14 @@
* @op: the operator the rule uses
* @rulestr: the text "target" of the rule
* @rule: pointer to the new rule structure returned via this
+ * @gfp: GFP flag used for kmalloc
*
* Returns 0 if successful, -errno if not. On success, the rule structure
* will be allocated internally. The caller must free this structure with
* selinux_audit_rule_free() after use.
*/
-int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule);
+int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule,
+ gfp_t gfp);
/**
* selinux_audit_rule_free - free an selinux audit rule structure.
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 24d7d8b3cda3..ba2ac3da1153 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -29,7 +29,7 @@
sizeof(unsigned long))
#define EBITMAP_UNIT_SIZE BITS_PER_LONG
#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
-#define EBITMAP_BIT 1ULL
+#define EBITMAP_BIT 1UL
#define EBITMAP_SHIFT_UNIT_SIZE(x) \
(((x) >> EBITMAP_UNIT_SIZE / 2) >> EBITMAP_UNIT_SIZE / 2)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index f20e1968b7f7..e33e55384b75 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3507,7 +3507,8 @@ void selinux_audit_rule_free(void *vrule)
}
}
-int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
+int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
+ gfp_t gfp)
{
struct selinux_state *state = &selinux_state;
struct selinux_policy *policy;
@@ -3548,7 +3549,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
return -EINVAL;
}
- tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL);
+ tmprule = kzalloc(sizeof(struct selinux_audit_rule), gfp);
if (!tmprule)
return -ENOMEM;
context_init(&tmprule->au_ctxt);