diff options
author | John Johansen <john.johansen@canonical.com> | 2017-01-16 00:43:06 -0800 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2017-01-16 01:18:49 -0800 |
commit | aa9a39ad8f60cc73e1bd2f18f0693bba6be8b067 (patch) | |
tree | bc45548c142995e83d9bbe81147286e2216dac3d /security/apparmor/domain.c | |
parent | c3e1e584ad3853b3f13ea4bd0aabd43e6c9b9fda (diff) |
apparmor: convert change_profile to use fqname later to give better control
Moving the use of fqname to later allows learning profiles to be based
on the fqname request instead of just the hname. It also allows cleaning
up some of the name parsing and lookup by allowing the use of
the fqlookupn_profile() lib fn.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/domain.c')
-rw-r--r-- | security/apparmor/domain.c | 61 |
1 files changed, 19 insertions, 42 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index d18b3f0e5534..ef4beef06e9d 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -729,8 +729,7 @@ out: /** * aa_change_profile - perform a one-way profile transition - * @ns_name: name of the profile namespace to change to (MAYBE NULL) - * @hname: name of profile to change to (MAYBE NULL) + * @fqname: name of profile may include namespace (NOT NULL) * @onexec: whether this transition is to take place immediately or at exec * @permtest: true if this is just a permission test * @@ -742,19 +741,20 @@ out: * * Returns %0 on success, error otherwise. */ -int aa_change_profile(const char *ns_name, const char *hname, bool onexec, - bool permtest) +int aa_change_profile(const char *fqname, bool onexec, + bool permtest, bool stack) { const struct cred *cred; struct aa_profile *profile, *target = NULL; - struct aa_ns *ns = NULL; struct file_perms perms = {}; - const char *name = NULL, *info = NULL, *op; + const char *info = NULL, *op; int error = 0; u32 request; - if (!hname && !ns_name) + if (!fqname || !*fqname) { + AA_DEBUG("no profile name"); return -EINVAL; + } if (onexec) { request = AA_MAY_ONEXEC; @@ -779,44 +779,15 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, return -EPERM; } - if (ns_name) { - /* released below */ - ns = aa_find_ns(profile->ns, ns_name); - if (!ns) { - /* we don't create new namespace in complain mode */ - name = ns_name; - info = "namespace not found"; - error = -ENOENT; - goto audit; - } - } else - /* released below */ - ns = aa_get_ns(profile->ns); - - /* if the name was not specified, use the name of the current profile */ - if (!hname) { - if (unconfined(profile)) - hname = ns->unconfined->base.hname; - else - hname = profile->base.hname; - } - - perms = change_profile_perms(profile, ns, hname, request, - profile->file.start); - if (!(perms.allow & request)) { - error = -EACCES; - goto audit; - } - - /* released below */ - target = aa_lookup_profile(ns, hname); + target = aa_fqlookupn_profile(profile, fqname, strlen(fqname)); if (!target) { info = "profile not found"; error = -ENOENT; if (permtest || !COMPLAIN_MODE(profile)) goto audit; /* released below */ - target = aa_new_null_profile(profile, false, hname, GFP_KERNEL); + target = aa_new_null_profile(profile, false, fqname, + GFP_KERNEL); if (!target) { info = "failed null profile create"; error = -ENOMEM; @@ -824,6 +795,13 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, } } + perms = change_profile_perms(profile, target->ns, target->base.hname, + request, profile->file.start); + if (!(perms.allow & request)) { + error = -EACCES; + goto audit; + } + /* check if tracing task is allowed to trace target domain */ error = may_change_ptraced_domain(target); if (error) { @@ -841,10 +819,9 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, audit: if (!permtest) - error = aa_audit_file(profile, &perms, op, request, name, - hname, GLOBAL_ROOT_UID, info, error); + error = aa_audit_file(profile, &perms, op, request, NULL, + fqname, GLOBAL_ROOT_UID, info, error); - aa_put_ns(ns); aa_put_profile(target); put_cred(cred); |