diff options
Diffstat (limited to 'security/apparmor/domain.c')
-rw-r--r-- | security/apparmor/domain.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 87dfa0e40398..ed4a13d44894 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -1311,6 +1311,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name, return error; } +const char *stack_msg = "change_profile unprivileged unconfined converted to stacking"; + /** * aa_change_profile - perform a one-way profile transition * @fqname: name of profile may include namespace (NOT NULL) @@ -1370,6 +1372,28 @@ int aa_change_profile(const char *fqname, int flags) op = OP_CHANGE_PROFILE; } + /* This should move to a per profile test. Requires pushing build + * into callback + */ + if (!stack && unconfined(label) && + label == &labels_ns(label)->unconfined->label && + aa_unprivileged_unconfined_restricted && + /* TODO: refactor so this check is a fn */ + cap_capable(current_cred(), &init_user_ns, CAP_MAC_OVERRIDE, + CAP_OPT_NOAUDIT)) { + /* regardless of the request in this case apparmor + * stacks against unconfined so admin set policy can't be + * by-passed + */ + stack = true; + perms.audit = request; + (void) fn_for_each_in_ns(label, profile, + aa_audit_file(subj_cred, profile, &perms, op, + request, auditname, NULL, target, + GLOBAL_ROOT_UID, stack_msg, 0)); + perms.audit = 0; + } + if (*fqname == '&') { stack = true; /* don't have label_parse() do stacking */ |