summaryrefslogtreecommitdiffstats
path: root/security/apparmor/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/domain.c')
-rw-r--r--security/apparmor/domain.c61
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);