summaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 735609b19e76..dddb81e06d2d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3107,6 +3107,18 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
return dentry_has_perm(cred, dentry, FILE__SETATTR);
}
+static bool has_cap_mac_admin(bool audit)
+{
+ const struct cred *cred = current_cred();
+ int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT;
+
+ if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit))
+ return false;
+ if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true))
+ return false;
+ return true;
+}
+
static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
@@ -3138,7 +3150,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
if (rc == -EINVAL) {
- if (!capable(CAP_MAC_ADMIN)) {
+ if (!has_cap_mac_admin(true)) {
struct audit_buffer *ab;
size_t audit_size;
const char *str;
@@ -3264,13 +3276,8 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
* and lack of permission just means that we fall back to the
* in-core context value, not a denial.
*/
- error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
- SECURITY_CAP_NOAUDIT);
- if (!error)
- error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
- SECURITY_CAP_NOAUDIT, true);
isec = inode_security(inode);
- if (!error)
+ if (has_cap_mac_admin(false))
error = security_sid_to_context_force(isec->sid, &context,
&size);
else
@@ -5919,7 +5926,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
}
error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
if (error == -EINVAL && !strcmp(name, "fscreate")) {
- if (!capable(CAP_MAC_ADMIN)) {
+ if (!has_cap_mac_admin(true)) {
struct audit_buffer *ab;
size_t audit_size;