Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AppArmor security module
0004  *
0005  * This file contains AppArmor policy attachment and domain transitions
0006  *
0007  * Copyright (C) 2002-2008 Novell/SUSE
0008  * Copyright 2009-2010 Canonical Ltd.
0009  */
0010 
0011 #include <linux/errno.h>
0012 #include <linux/fdtable.h>
0013 #include <linux/fs.h>
0014 #include <linux/file.h>
0015 #include <linux/mount.h>
0016 #include <linux/syscalls.h>
0017 #include <linux/personality.h>
0018 #include <linux/xattr.h>
0019 #include <linux/user_namespace.h>
0020 
0021 #include "include/audit.h"
0022 #include "include/apparmorfs.h"
0023 #include "include/cred.h"
0024 #include "include/domain.h"
0025 #include "include/file.h"
0026 #include "include/ipc.h"
0027 #include "include/match.h"
0028 #include "include/path.h"
0029 #include "include/policy.h"
0030 #include "include/policy_ns.h"
0031 
0032 /**
0033  * aa_free_domain_entries - free entries in a domain table
0034  * @domain: the domain table to free  (MAYBE NULL)
0035  */
0036 void aa_free_domain_entries(struct aa_domain *domain)
0037 {
0038     int i;
0039     if (domain) {
0040         if (!domain->table)
0041             return;
0042 
0043         for (i = 0; i < domain->size; i++)
0044             kfree_sensitive(domain->table[i]);
0045         kfree_sensitive(domain->table);
0046         domain->table = NULL;
0047     }
0048 }
0049 
0050 /**
0051  * may_change_ptraced_domain - check if can change profile on ptraced task
0052  * @to_label: profile to change to  (NOT NULL)
0053  * @info: message if there is an error
0054  *
0055  * Check if current is ptraced and if so if the tracing task is allowed
0056  * to trace the new domain
0057  *
0058  * Returns: %0 or error if change not allowed
0059  */
0060 static int may_change_ptraced_domain(struct aa_label *to_label,
0061                      const char **info)
0062 {
0063     struct task_struct *tracer;
0064     struct aa_label *tracerl = NULL;
0065     int error = 0;
0066 
0067     rcu_read_lock();
0068     tracer = ptrace_parent(current);
0069     if (tracer)
0070         /* released below */
0071         tracerl = aa_get_task_label(tracer);
0072 
0073     /* not ptraced */
0074     if (!tracer || unconfined(tracerl))
0075         goto out;
0076 
0077     error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
0078 
0079 out:
0080     rcu_read_unlock();
0081     aa_put_label(tracerl);
0082 
0083     if (error)
0084         *info = "ptrace prevents transition";
0085     return error;
0086 }
0087 
0088 /**** TODO: dedup to aa_label_match - needs perm and dfa, merging
0089  * specifically this is an exact copy of aa_label_match except
0090  * aa_compute_perms is replaced with aa_compute_fperms
0091  * and policy.dfa with file.dfa
0092  ****/
0093 /* match a profile and its associated ns component if needed
0094  * Assumes visibility test has already been done.
0095  * If a subns profile is not to be matched should be prescreened with
0096  * visibility test.
0097  */
0098 static inline unsigned int match_component(struct aa_profile *profile,
0099                        struct aa_profile *tp,
0100                        bool stack, unsigned int state)
0101 {
0102     const char *ns_name;
0103 
0104     if (stack)
0105         state = aa_dfa_match(profile->file.dfa, state, "&");
0106     if (profile->ns == tp->ns)
0107         return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
0108 
0109     /* try matching with namespace name and then profile */
0110     ns_name = aa_ns_name(profile->ns, tp->ns, true);
0111     state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
0112     state = aa_dfa_match(profile->file.dfa, state, ns_name);
0113     state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
0114     return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
0115 }
0116 
0117 /**
0118  * label_compound_match - find perms for full compound label
0119  * @profile: profile to find perms for
0120  * @label: label to check access permissions for
0121  * @stack: whether this is a stacking request
0122  * @state: state to start match in
0123  * @subns: whether to do permission checks on components in a subns
0124  * @request: permissions to request
0125  * @perms: perms struct to set
0126  *
0127  * Returns: 0 on success else ERROR
0128  *
0129  * For the label A//&B//&C this does the perm match for A//&B//&C
0130  * @perms should be preinitialized with allperms OR a previous permission
0131  *        check to be stacked.
0132  */
0133 static int label_compound_match(struct aa_profile *profile,
0134                 struct aa_label *label, bool stack,
0135                 unsigned int state, bool subns, u32 request,
0136                 struct aa_perms *perms)
0137 {
0138     struct aa_profile *tp;
0139     struct label_it i;
0140     struct path_cond cond = { };
0141 
0142     /* find first subcomponent that is visible */
0143     label_for_each(i, label, tp) {
0144         if (!aa_ns_visible(profile->ns, tp->ns, subns))
0145             continue;
0146         state = match_component(profile, tp, stack, state);
0147         if (!state)
0148             goto fail;
0149         goto next;
0150     }
0151 
0152     /* no component visible */
0153     *perms = allperms;
0154     return 0;
0155 
0156 next:
0157     label_for_each_cont(i, label, tp) {
0158         if (!aa_ns_visible(profile->ns, tp->ns, subns))
0159             continue;
0160         state = aa_dfa_match(profile->file.dfa, state, "//&");
0161         state = match_component(profile, tp, false, state);
0162         if (!state)
0163             goto fail;
0164     }
0165     *perms = aa_compute_fperms(profile->file.dfa, state, &cond);
0166     aa_apply_modes_to_perms(profile, perms);
0167     if ((perms->allow & request) != request)
0168         return -EACCES;
0169 
0170     return 0;
0171 
0172 fail:
0173     *perms = nullperms;
0174     return -EACCES;
0175 }
0176 
0177 /**
0178  * label_components_match - find perms for all subcomponents of a label
0179  * @profile: profile to find perms for
0180  * @label: label to check access permissions for
0181  * @stack: whether this is a stacking request
0182  * @start: state to start match in
0183  * @subns: whether to do permission checks on components in a subns
0184  * @request: permissions to request
0185  * @perms: an initialized perms struct to add accumulation to
0186  *
0187  * Returns: 0 on success else ERROR
0188  *
0189  * For the label A//&B//&C this does the perm match for each of A and B and C
0190  * @perms should be preinitialized with allperms OR a previous permission
0191  *        check to be stacked.
0192  */
0193 static int label_components_match(struct aa_profile *profile,
0194                   struct aa_label *label, bool stack,
0195                   unsigned int start, bool subns, u32 request,
0196                   struct aa_perms *perms)
0197 {
0198     struct aa_profile *tp;
0199     struct label_it i;
0200     struct aa_perms tmp;
0201     struct path_cond cond = { };
0202     unsigned int state = 0;
0203 
0204     /* find first subcomponent to test */
0205     label_for_each(i, label, tp) {
0206         if (!aa_ns_visible(profile->ns, tp->ns, subns))
0207             continue;
0208         state = match_component(profile, tp, stack, start);
0209         if (!state)
0210             goto fail;
0211         goto next;
0212     }
0213 
0214     /* no subcomponents visible - no change in perms */
0215     return 0;
0216 
0217 next:
0218     tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
0219     aa_apply_modes_to_perms(profile, &tmp);
0220     aa_perms_accum(perms, &tmp);
0221     label_for_each_cont(i, label, tp) {
0222         if (!aa_ns_visible(profile->ns, tp->ns, subns))
0223             continue;
0224         state = match_component(profile, tp, stack, start);
0225         if (!state)
0226             goto fail;
0227         tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
0228         aa_apply_modes_to_perms(profile, &tmp);
0229         aa_perms_accum(perms, &tmp);
0230     }
0231 
0232     if ((perms->allow & request) != request)
0233         return -EACCES;
0234 
0235     return 0;
0236 
0237 fail:
0238     *perms = nullperms;
0239     return -EACCES;
0240 }
0241 
0242 /**
0243  * label_match - do a multi-component label match
0244  * @profile: profile to match against (NOT NULL)
0245  * @label: label to match (NOT NULL)
0246  * @stack: whether this is a stacking request
0247  * @state: state to start in
0248  * @subns: whether to match subns components
0249  * @request: permission request
0250  * @perms: Returns computed perms (NOT NULL)
0251  *
0252  * Returns: the state the match finished in, may be the none matching state
0253  */
0254 static int label_match(struct aa_profile *profile, struct aa_label *label,
0255                bool stack, unsigned int state, bool subns, u32 request,
0256                struct aa_perms *perms)
0257 {
0258     int error;
0259 
0260     *perms = nullperms;
0261     error = label_compound_match(profile, label, stack, state, subns,
0262                      request, perms);
0263     if (!error)
0264         return error;
0265 
0266     *perms = allperms;
0267     return label_components_match(profile, label, stack, state, subns,
0268                       request, perms);
0269 }
0270 
0271 /******* end TODO: dedup *****/
0272 
0273 /**
0274  * change_profile_perms - find permissions for change_profile
0275  * @profile: the current profile  (NOT NULL)
0276  * @target: label to transition to (NOT NULL)
0277  * @stack: whether this is a stacking request
0278  * @request: requested perms
0279  * @start: state to start matching in
0280  *
0281  *
0282  * Returns: permission set
0283  *
0284  * currently only matches full label A//&B//&C or individual components A, B, C
0285  * not arbitrary combinations. Eg. A//&B, C
0286  */
0287 static int change_profile_perms(struct aa_profile *profile,
0288                 struct aa_label *target, bool stack,
0289                 u32 request, unsigned int start,
0290                 struct aa_perms *perms)
0291 {
0292     if (profile_unconfined(profile)) {
0293         perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
0294         perms->audit = perms->quiet = perms->kill = 0;
0295         return 0;
0296     }
0297 
0298     /* TODO: add profile in ns screening */
0299     return label_match(profile, target, stack, start, true, request, perms);
0300 }
0301 
0302 /**
0303  * aa_xattrs_match - check whether a file matches the xattrs defined in profile
0304  * @bprm: binprm struct for the process to validate
0305  * @profile: profile to match against (NOT NULL)
0306  * @state: state to start match in
0307  *
0308  * Returns: number of extended attributes that matched, or < 0 on error
0309  */
0310 static int aa_xattrs_match(const struct linux_binprm *bprm,
0311                struct aa_profile *profile, unsigned int state)
0312 {
0313     int i;
0314     ssize_t size;
0315     struct dentry *d;
0316     char *value = NULL;
0317     int value_size = 0, ret = profile->xattr_count;
0318 
0319     if (!bprm || !profile->xattr_count)
0320         return 0;
0321     might_sleep();
0322 
0323     /* transition from exec match to xattr set */
0324     state = aa_dfa_outofband_transition(profile->xmatch, state);
0325     d = bprm->file->f_path.dentry;
0326 
0327     for (i = 0; i < profile->xattr_count; i++) {
0328         size = vfs_getxattr_alloc(&init_user_ns, d, profile->xattrs[i],
0329                       &value, value_size, GFP_KERNEL);
0330         if (size >= 0) {
0331             u32 perm;
0332 
0333             /*
0334              * Check the xattr presence before value. This ensure
0335              * that not present xattr can be distinguished from a 0
0336              * length value or rule that matches any value
0337              */
0338             state = aa_dfa_null_transition(profile->xmatch, state);
0339             /* Check xattr value */
0340             state = aa_dfa_match_len(profile->xmatch, state, value,
0341                          size);
0342             perm = dfa_user_allow(profile->xmatch, state);
0343             if (!(perm & MAY_EXEC)) {
0344                 ret = -EINVAL;
0345                 goto out;
0346             }
0347         }
0348         /* transition to next element */
0349         state = aa_dfa_outofband_transition(profile->xmatch, state);
0350         if (size < 0) {
0351             /*
0352              * No xattr match, so verify if transition to
0353              * next element was valid. IFF so the xattr
0354              * was optional.
0355              */
0356             if (!state) {
0357                 ret = -EINVAL;
0358                 goto out;
0359             }
0360             /* don't count missing optional xattr as matched */
0361             ret--;
0362         }
0363     }
0364 
0365 out:
0366     kfree(value);
0367     return ret;
0368 }
0369 
0370 /**
0371  * find_attach - do attachment search for unconfined processes
0372  * @bprm - binprm structure of transitioning task
0373  * @ns: the current namespace  (NOT NULL)
0374  * @head - profile list to walk  (NOT NULL)
0375  * @name - to match against  (NOT NULL)
0376  * @info - info message if there was an error (NOT NULL)
0377  *
0378  * Do a linear search on the profiles in the list.  There is a matching
0379  * preference where an exact match is preferred over a name which uses
0380  * expressions to match, and matching expressions with the greatest
0381  * xmatch_len are preferred.
0382  *
0383  * Requires: @head not be shared or have appropriate locks held
0384  *
0385  * Returns: label or NULL if no match found
0386  */
0387 static struct aa_label *find_attach(const struct linux_binprm *bprm,
0388                     struct aa_ns *ns, struct list_head *head,
0389                     const char *name, const char **info)
0390 {
0391     int candidate_len = 0, candidate_xattrs = 0;
0392     bool conflict = false;
0393     struct aa_profile *profile, *candidate = NULL;
0394 
0395     AA_BUG(!name);
0396     AA_BUG(!head);
0397 
0398     rcu_read_lock();
0399 restart:
0400     list_for_each_entry_rcu(profile, head, base.list) {
0401         if (profile->label.flags & FLAG_NULL &&
0402             &profile->label == ns_unconfined(profile->ns))
0403             continue;
0404 
0405         /* Find the "best" matching profile. Profiles must
0406          * match the path and extended attributes (if any)
0407          * associated with the file. A more specific path
0408          * match will be preferred over a less specific one,
0409          * and a match with more matching extended attributes
0410          * will be preferred over one with fewer. If the best
0411          * match has both the same level of path specificity
0412          * and the same number of matching extended attributes
0413          * as another profile, signal a conflict and refuse to
0414          * match.
0415          */
0416         if (profile->xmatch) {
0417             unsigned int state, count;
0418             u32 perm;
0419 
0420             state = aa_dfa_leftmatch(profile->xmatch, DFA_START,
0421                          name, &count);
0422             perm = dfa_user_allow(profile->xmatch, state);
0423             /* any accepting state means a valid match. */
0424             if (perm & MAY_EXEC) {
0425                 int ret = 0;
0426 
0427                 if (count < candidate_len)
0428                     continue;
0429 
0430                 if (bprm && profile->xattr_count) {
0431                     long rev = READ_ONCE(ns->revision);
0432 
0433                     if (!aa_get_profile_not0(profile))
0434                         goto restart;
0435                     rcu_read_unlock();
0436                     ret = aa_xattrs_match(bprm, profile,
0437                                   state);
0438                     rcu_read_lock();
0439                     aa_put_profile(profile);
0440                     if (rev !=
0441                         READ_ONCE(ns->revision))
0442                         /* policy changed */
0443                         goto restart;
0444                     /*
0445                      * Fail matching if the xattrs don't
0446                      * match
0447                      */
0448                     if (ret < 0)
0449                         continue;
0450                 }
0451                 /*
0452                  * TODO: allow for more flexible best match
0453                  *
0454                  * The new match isn't more specific
0455                  * than the current best match
0456                  */
0457                 if (count == candidate_len &&
0458                     ret <= candidate_xattrs) {
0459                     /* Match is equivalent, so conflict */
0460                     if (ret == candidate_xattrs)
0461                         conflict = true;
0462                     continue;
0463                 }
0464 
0465                 /* Either the same length with more matching
0466                  * xattrs, or a longer match
0467                  */
0468                 candidate = profile;
0469                 candidate_len = max(count, profile->xmatch_len);
0470                 candidate_xattrs = ret;
0471                 conflict = false;
0472             }
0473         } else if (!strcmp(profile->base.name, name)) {
0474             /*
0475              * old exact non-re match, without conditionals such
0476              * as xattrs. no more searching required
0477              */
0478             candidate = profile;
0479             goto out;
0480         }
0481     }
0482 
0483     if (!candidate || conflict) {
0484         if (conflict)
0485             *info = "conflicting profile attachments";
0486         rcu_read_unlock();
0487         return NULL;
0488     }
0489 
0490 out:
0491     candidate = aa_get_newest_profile(candidate);
0492     rcu_read_unlock();
0493 
0494     return &candidate->label;
0495 }
0496 
0497 static const char *next_name(int xtype, const char *name)
0498 {
0499     return NULL;
0500 }
0501 
0502 /**
0503  * x_table_lookup - lookup an x transition name via transition table
0504  * @profile: current profile (NOT NULL)
0505  * @xindex: index into x transition table
0506  * @name: returns: name tested to find label (NOT NULL)
0507  *
0508  * Returns: refcounted label, or NULL on failure (MAYBE NULL)
0509  */
0510 struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
0511                 const char **name)
0512 {
0513     struct aa_label *label = NULL;
0514     u32 xtype = xindex & AA_X_TYPE_MASK;
0515     int index = xindex & AA_X_INDEX_MASK;
0516 
0517     AA_BUG(!name);
0518 
0519     /* index is guaranteed to be in range, validated at load time */
0520     /* TODO: move lookup parsing to unpack time so this is a straight
0521      *       index into the resultant label
0522      */
0523     for (*name = profile->file.trans.table[index]; !label && *name;
0524          *name = next_name(xtype, *name)) {
0525         if (xindex & AA_X_CHILD) {
0526             struct aa_profile *new_profile;
0527             /* release by caller */
0528             new_profile = aa_find_child(profile, *name);
0529             if (new_profile)
0530                 label = &new_profile->label;
0531             continue;
0532         }
0533         label = aa_label_parse(&profile->label, *name, GFP_KERNEL,
0534                        true, false);
0535         if (IS_ERR(label))
0536             label = NULL;
0537     }
0538 
0539     /* released by caller */
0540 
0541     return label;
0542 }
0543 
0544 /**
0545  * x_to_label - get target label for a given xindex
0546  * @profile: current profile  (NOT NULL)
0547  * @bprm: binprm structure of transitioning task
0548  * @name: name to lookup (NOT NULL)
0549  * @xindex: index into x transition table
0550  * @lookupname: returns: name used in lookup if one was specified (NOT NULL)
0551  *
0552  * find label for a transition index
0553  *
0554  * Returns: refcounted label or NULL if not found available
0555  */
0556 static struct aa_label *x_to_label(struct aa_profile *profile,
0557                    const struct linux_binprm *bprm,
0558                    const char *name, u32 xindex,
0559                    const char **lookupname,
0560                    const char **info)
0561 {
0562     struct aa_label *new = NULL;
0563     struct aa_ns *ns = profile->ns;
0564     u32 xtype = xindex & AA_X_TYPE_MASK;
0565     const char *stack = NULL;
0566 
0567     switch (xtype) {
0568     case AA_X_NONE:
0569         /* fail exec unless ix || ux fallback - handled by caller */
0570         *lookupname = NULL;
0571         break;
0572     case AA_X_TABLE:
0573         /* TODO: fix when perm mapping done at unload */
0574         stack = profile->file.trans.table[xindex & AA_X_INDEX_MASK];
0575         if (*stack != '&') {
0576             /* released by caller */
0577             new = x_table_lookup(profile, xindex, lookupname);
0578             stack = NULL;
0579             break;
0580         }
0581         fallthrough;    /* to X_NAME */
0582     case AA_X_NAME:
0583         if (xindex & AA_X_CHILD)
0584             /* released by caller */
0585             new = find_attach(bprm, ns, &profile->base.profiles,
0586                       name, info);
0587         else
0588             /* released by caller */
0589             new = find_attach(bprm, ns, &ns->base.profiles,
0590                       name, info);
0591         *lookupname = name;
0592         break;
0593     }
0594 
0595     if (!new) {
0596         if (xindex & AA_X_INHERIT) {
0597             /* (p|c|n)ix - don't change profile but do
0598              * use the newest version
0599              */
0600             *info = "ix fallback";
0601             /* no profile && no error */
0602             new = aa_get_newest_label(&profile->label);
0603         } else if (xindex & AA_X_UNCONFINED) {
0604             new = aa_get_newest_label(ns_unconfined(profile->ns));
0605             *info = "ux fallback";
0606         }
0607     }
0608 
0609     if (new && stack) {
0610         /* base the stack on post domain transition */
0611         struct aa_label *base = new;
0612 
0613         new = aa_label_parse(base, stack, GFP_KERNEL, true, false);
0614         if (IS_ERR(new))
0615             new = NULL;
0616         aa_put_label(base);
0617     }
0618 
0619     /* released by caller */
0620     return new;
0621 }
0622 
0623 static struct aa_label *profile_transition(struct aa_profile *profile,
0624                        const struct linux_binprm *bprm,
0625                        char *buffer, struct path_cond *cond,
0626                        bool *secure_exec)
0627 {
0628     struct aa_label *new = NULL;
0629     const char *info = NULL, *name = NULL, *target = NULL;
0630     unsigned int state = profile->file.start;
0631     struct aa_perms perms = {};
0632     bool nonewprivs = false;
0633     int error = 0;
0634 
0635     AA_BUG(!profile);
0636     AA_BUG(!bprm);
0637     AA_BUG(!buffer);
0638 
0639     error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
0640                  &name, &info, profile->disconnected);
0641     if (error) {
0642         if (profile_unconfined(profile) ||
0643             (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
0644             AA_DEBUG("name lookup ix on error");
0645             error = 0;
0646             new = aa_get_newest_label(&profile->label);
0647         }
0648         name = bprm->filename;
0649         goto audit;
0650     }
0651 
0652     if (profile_unconfined(profile)) {
0653         new = find_attach(bprm, profile->ns,
0654                   &profile->ns->base.profiles, name, &info);
0655         if (new) {
0656             AA_DEBUG("unconfined attached to new label");
0657             return new;
0658         }
0659         AA_DEBUG("unconfined exec no attachment");
0660         return aa_get_newest_label(&profile->label);
0661     }
0662 
0663     /* find exec permissions for name */
0664     state = aa_str_perms(profile->file.dfa, state, name, cond, &perms);
0665     if (perms.allow & MAY_EXEC) {
0666         /* exec permission determine how to transition */
0667         new = x_to_label(profile, bprm, name, perms.xindex, &target,
0668                  &info);
0669         if (new && new->proxy == profile->label.proxy && info) {
0670             /* hack ix fallback - improve how this is detected */
0671             goto audit;
0672         } else if (!new) {
0673             error = -EACCES;
0674             info = "profile transition not found";
0675             /* remove MAY_EXEC to audit as failure */
0676             perms.allow &= ~MAY_EXEC;
0677         }
0678     } else if (COMPLAIN_MODE(profile)) {
0679         /* no exec permission - learning mode */
0680         struct aa_profile *new_profile = NULL;
0681 
0682         new_profile = aa_new_null_profile(profile, false, name,
0683                           GFP_KERNEL);
0684         if (!new_profile) {
0685             error = -ENOMEM;
0686             info = "could not create null profile";
0687         } else {
0688             error = -EACCES;
0689             new = &new_profile->label;
0690         }
0691         perms.xindex |= AA_X_UNSAFE;
0692     } else
0693         /* fail exec */
0694         error = -EACCES;
0695 
0696     if (!new)
0697         goto audit;
0698 
0699 
0700     if (!(perms.xindex & AA_X_UNSAFE)) {
0701         if (DEBUG_ON) {
0702             dbg_printk("apparmor: scrubbing environment variables"
0703                    " for %s profile=", name);
0704             aa_label_printk(new, GFP_KERNEL);
0705             dbg_printk("\n");
0706         }
0707         *secure_exec = true;
0708     }
0709 
0710 audit:
0711     aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new,
0712               cond->uid, info, error);
0713     if (!new || nonewprivs) {
0714         aa_put_label(new);
0715         return ERR_PTR(error);
0716     }
0717 
0718     return new;
0719 }
0720 
0721 static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
0722               bool stack, const struct linux_binprm *bprm,
0723               char *buffer, struct path_cond *cond,
0724               bool *secure_exec)
0725 {
0726     unsigned int state = profile->file.start;
0727     struct aa_perms perms = {};
0728     const char *xname = NULL, *info = "change_profile onexec";
0729     int error = -EACCES;
0730 
0731     AA_BUG(!profile);
0732     AA_BUG(!onexec);
0733     AA_BUG(!bprm);
0734     AA_BUG(!buffer);
0735 
0736     if (profile_unconfined(profile)) {
0737         /* change_profile on exec already granted */
0738         /*
0739          * NOTE: Domain transitions from unconfined are allowed
0740          * even when no_new_privs is set because this aways results
0741          * in a further reduction of permissions.
0742          */
0743         return 0;
0744     }
0745 
0746     error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
0747                  &xname, &info, profile->disconnected);
0748     if (error) {
0749         if (profile_unconfined(profile) ||
0750             (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
0751             AA_DEBUG("name lookup ix on error");
0752             error = 0;
0753         }
0754         xname = bprm->filename;
0755         goto audit;
0756     }
0757 
0758     /* find exec permissions for name */
0759     state = aa_str_perms(profile->file.dfa, state, xname, cond, &perms);
0760     if (!(perms.allow & AA_MAY_ONEXEC)) {
0761         info = "no change_onexec valid for executable";
0762         goto audit;
0763     }
0764     /* test if this exec can be paired with change_profile onexec.
0765      * onexec permission is linked to exec with a standard pairing
0766      * exec\0change_profile
0767      */
0768     state = aa_dfa_null_transition(profile->file.dfa, state);
0769     error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC,
0770                      state, &perms);
0771     if (error) {
0772         perms.allow &= ~AA_MAY_ONEXEC;
0773         goto audit;
0774     }
0775 
0776     if (!(perms.xindex & AA_X_UNSAFE)) {
0777         if (DEBUG_ON) {
0778             dbg_printk("apparmor: scrubbing environment "
0779                    "variables for %s label=", xname);
0780             aa_label_printk(onexec, GFP_KERNEL);
0781             dbg_printk("\n");
0782         }
0783         *secure_exec = true;
0784     }
0785 
0786 audit:
0787     return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname,
0788                  NULL, onexec, cond->uid, info, error);
0789 }
0790 
0791 /* ensure none ns domain transitions are correctly applied with onexec */
0792 
0793 static struct aa_label *handle_onexec(struct aa_label *label,
0794                       struct aa_label *onexec, bool stack,
0795                       const struct linux_binprm *bprm,
0796                       char *buffer, struct path_cond *cond,
0797                       bool *unsafe)
0798 {
0799     struct aa_profile *profile;
0800     struct aa_label *new;
0801     int error;
0802 
0803     AA_BUG(!label);
0804     AA_BUG(!onexec);
0805     AA_BUG(!bprm);
0806     AA_BUG(!buffer);
0807 
0808     if (!stack) {
0809         error = fn_for_each_in_ns(label, profile,
0810                 profile_onexec(profile, onexec, stack,
0811                            bprm, buffer, cond, unsafe));
0812         if (error)
0813             return ERR_PTR(error);
0814         new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
0815                 aa_get_newest_label(onexec),
0816                 profile_transition(profile, bprm, buffer,
0817                            cond, unsafe));
0818 
0819     } else {
0820         /* TODO: determine how much we want to loosen this */
0821         error = fn_for_each_in_ns(label, profile,
0822                 profile_onexec(profile, onexec, stack, bprm,
0823                            buffer, cond, unsafe));
0824         if (error)
0825             return ERR_PTR(error);
0826         new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
0827                 aa_label_merge(&profile->label, onexec,
0828                            GFP_KERNEL),
0829                 profile_transition(profile, bprm, buffer,
0830                            cond, unsafe));
0831     }
0832 
0833     if (new)
0834         return new;
0835 
0836     /* TODO: get rid of GLOBAL_ROOT_UID */
0837     error = fn_for_each_in_ns(label, profile,
0838             aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC,
0839                       AA_MAY_ONEXEC, bprm->filename, NULL,
0840                       onexec, GLOBAL_ROOT_UID,
0841                       "failed to build target label", -ENOMEM));
0842     return ERR_PTR(error);
0843 }
0844 
0845 /**
0846  * apparmor_bprm_creds_for_exec - Update the new creds on the bprm struct
0847  * @bprm: binprm for the exec  (NOT NULL)
0848  *
0849  * Returns: %0 or error on failure
0850  *
0851  * TODO: once the other paths are done see if we can't refactor into a fn
0852  */
0853 int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
0854 {
0855     struct aa_task_ctx *ctx;
0856     struct aa_label *label, *new = NULL;
0857     struct aa_profile *profile;
0858     char *buffer = NULL;
0859     const char *info = NULL;
0860     int error = 0;
0861     bool unsafe = false;
0862     kuid_t i_uid = i_uid_into_mnt(file_mnt_user_ns(bprm->file),
0863                       file_inode(bprm->file));
0864     struct path_cond cond = {
0865         i_uid,
0866         file_inode(bprm->file)->i_mode
0867     };
0868 
0869     ctx = task_ctx(current);
0870     AA_BUG(!cred_label(bprm->cred));
0871     AA_BUG(!ctx);
0872 
0873     label = aa_get_newest_label(cred_label(bprm->cred));
0874 
0875     /*
0876      * Detect no new privs being set, and store the label it
0877      * occurred under. Ideally this would happen when nnp
0878      * is set but there isn't a good way to do that yet.
0879      *
0880      * Testing for unconfined must be done before the subset test
0881      */
0882     if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) && !unconfined(label) &&
0883         !ctx->nnp)
0884         ctx->nnp = aa_get_label(label);
0885 
0886     /* buffer freed below, name is pointer into buffer */
0887     buffer = aa_get_buffer(false);
0888     if (!buffer) {
0889         error = -ENOMEM;
0890         goto done;
0891     }
0892 
0893     /* Test for onexec first as onexec override other x transitions. */
0894     if (ctx->onexec)
0895         new = handle_onexec(label, ctx->onexec, ctx->token,
0896                     bprm, buffer, &cond, &unsafe);
0897     else
0898         new = fn_label_build(label, profile, GFP_KERNEL,
0899                 profile_transition(profile, bprm, buffer,
0900                            &cond, &unsafe));
0901 
0902     AA_BUG(!new);
0903     if (IS_ERR(new)) {
0904         error = PTR_ERR(new);
0905         goto done;
0906     } else if (!new) {
0907         error = -ENOMEM;
0908         goto done;
0909     }
0910 
0911     /* Policy has specified a domain transitions. If no_new_privs and
0912      * confined ensure the transition is to confinement that is subset
0913      * of the confinement when the task entered no new privs.
0914      *
0915      * NOTE: Domain transitions from unconfined and to stacked
0916      * subsets are allowed even when no_new_privs is set because this
0917      * aways results in a further reduction of permissions.
0918      */
0919     if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
0920         !unconfined(label) &&
0921         !aa_label_is_unconfined_subset(new, ctx->nnp)) {
0922         error = -EPERM;
0923         info = "no new privs";
0924         goto audit;
0925     }
0926 
0927     if (bprm->unsafe & LSM_UNSAFE_SHARE) {
0928         /* FIXME: currently don't mediate shared state */
0929         ;
0930     }
0931 
0932     if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) {
0933         /* TODO: test needs to be profile of label to new */
0934         error = may_change_ptraced_domain(new, &info);
0935         if (error)
0936             goto audit;
0937     }
0938 
0939     if (unsafe) {
0940         if (DEBUG_ON) {
0941             dbg_printk("scrubbing environment variables for %s "
0942                    "label=", bprm->filename);
0943             aa_label_printk(new, GFP_KERNEL);
0944             dbg_printk("\n");
0945         }
0946         bprm->secureexec = 1;
0947     }
0948 
0949     if (label->proxy != new->proxy) {
0950         /* when transitioning clear unsafe personality bits */
0951         if (DEBUG_ON) {
0952             dbg_printk("apparmor: clearing unsafe personality "
0953                    "bits. %s label=", bprm->filename);
0954             aa_label_printk(new, GFP_KERNEL);
0955             dbg_printk("\n");
0956         }
0957         bprm->per_clear |= PER_CLEAR_ON_SETID;
0958     }
0959     aa_put_label(cred_label(bprm->cred));
0960     /* transfer reference, released when cred is freed */
0961     set_cred_label(bprm->cred, new);
0962 
0963 done:
0964     aa_put_label(label);
0965     aa_put_buffer(buffer);
0966 
0967     return error;
0968 
0969 audit:
0970     error = fn_for_each(label, profile,
0971             aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC,
0972                       bprm->filename, NULL, new,
0973                       i_uid, info, error));
0974     aa_put_label(new);
0975     goto done;
0976 }
0977 
0978 /*
0979  * Functions for self directed profile change
0980  */
0981 
0982 
0983 /* helper fn for change_hat
0984  *
0985  * Returns: label for hat transition OR ERR_PTR.  Does NOT return NULL
0986  */
0987 static struct aa_label *build_change_hat(struct aa_profile *profile,
0988                      const char *name, bool sibling)
0989 {
0990     struct aa_profile *root, *hat = NULL;
0991     const char *info = NULL;
0992     int error = 0;
0993 
0994     if (sibling && PROFILE_IS_HAT(profile)) {
0995         root = aa_get_profile_rcu(&profile->parent);
0996     } else if (!sibling && !PROFILE_IS_HAT(profile)) {
0997         root = aa_get_profile(profile);
0998     } else {
0999         info = "conflicting target types";
1000         error = -EPERM;
1001         goto audit;
1002     }
1003 
1004     hat = aa_find_child(root, name);
1005     if (!hat) {
1006         error = -ENOENT;
1007         if (COMPLAIN_MODE(profile)) {
1008             hat = aa_new_null_profile(profile, true, name,
1009                           GFP_KERNEL);
1010             if (!hat) {
1011                 info = "failed null profile create";
1012                 error = -ENOMEM;
1013             }
1014         }
1015     }
1016     aa_put_profile(root);
1017 
1018 audit:
1019     aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
1020               name, hat ? hat->base.hname : NULL,
1021               hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
1022               error);
1023     if (!hat || (error && error != -ENOENT))
1024         return ERR_PTR(error);
1025     /* if hat && error - complain mode, already audited and we adjust for
1026      * complain mode allow by returning hat->label
1027      */
1028     return &hat->label;
1029 }
1030 
1031 /* helper fn for changing into a hat
1032  *
1033  * Returns: label for hat transition or ERR_PTR. Does not return NULL
1034  */
1035 static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
1036                    int count, int flags)
1037 {
1038     struct aa_profile *profile, *root, *hat = NULL;
1039     struct aa_label *new;
1040     struct label_it it;
1041     bool sibling = false;
1042     const char *name, *info = NULL;
1043     int i, error;
1044 
1045     AA_BUG(!label);
1046     AA_BUG(!hats);
1047     AA_BUG(count < 1);
1048 
1049     if (PROFILE_IS_HAT(labels_profile(label)))
1050         sibling = true;
1051 
1052     /*find first matching hat */
1053     for (i = 0; i < count && !hat; i++) {
1054         name = hats[i];
1055         label_for_each_in_ns(it, labels_ns(label), label, profile) {
1056             if (sibling && PROFILE_IS_HAT(profile)) {
1057                 root = aa_get_profile_rcu(&profile->parent);
1058             } else if (!sibling && !PROFILE_IS_HAT(profile)) {
1059                 root = aa_get_profile(profile);
1060             } else {    /* conflicting change type */
1061                 info = "conflicting targets types";
1062                 error = -EPERM;
1063                 goto fail;
1064             }
1065             hat = aa_find_child(root, name);
1066             aa_put_profile(root);
1067             if (!hat) {
1068                 if (!COMPLAIN_MODE(profile))
1069                     goto outer_continue;
1070                 /* complain mode succeed as if hat */
1071             } else if (!PROFILE_IS_HAT(hat)) {
1072                 info = "target not hat";
1073                 error = -EPERM;
1074                 aa_put_profile(hat);
1075                 goto fail;
1076             }
1077             aa_put_profile(hat);
1078         }
1079         /* found a hat for all profiles in ns */
1080         goto build;
1081 outer_continue:
1082     ;
1083     }
1084     /* no hats that match, find appropriate error
1085      *
1086      * In complain mode audit of the failure is based off of the first
1087      * hat supplied.  This is done due how userspace interacts with
1088      * change_hat.
1089      */
1090     name = NULL;
1091     label_for_each_in_ns(it, labels_ns(label), label, profile) {
1092         if (!list_empty(&profile->base.profiles)) {
1093             info = "hat not found";
1094             error = -ENOENT;
1095             goto fail;
1096         }
1097     }
1098     info = "no hats defined";
1099     error = -ECHILD;
1100 
1101 fail:
1102     label_for_each_in_ns(it, labels_ns(label), label, profile) {
1103         /*
1104          * no target as it has failed to be found or built
1105          *
1106          * change_hat uses probing and should not log failures
1107          * related to missing hats
1108          */
1109         /* TODO: get rid of GLOBAL_ROOT_UID */
1110         if (count > 1 || COMPLAIN_MODE(profile)) {
1111             aa_audit_file(profile, &nullperms, OP_CHANGE_HAT,
1112                       AA_MAY_CHANGEHAT, name, NULL, NULL,
1113                       GLOBAL_ROOT_UID, info, error);
1114         }
1115     }
1116     return ERR_PTR(error);
1117 
1118 build:
1119     new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1120                    build_change_hat(profile, name, sibling),
1121                    aa_get_label(&profile->label));
1122     if (!new) {
1123         info = "label build failed";
1124         error = -ENOMEM;
1125         goto fail;
1126     } /* else if (IS_ERR) build_change_hat has logged error so return new */
1127 
1128     return new;
1129 }
1130 
1131 /**
1132  * aa_change_hat - change hat to/from subprofile
1133  * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0)
1134  * @count: number of hat names in @hats
1135  * @token: magic value to validate the hat change
1136  * @flags: flags affecting behavior of the change
1137  *
1138  * Returns %0 on success, error otherwise.
1139  *
1140  * Change to the first profile specified in @hats that exists, and store
1141  * the @hat_magic in the current task context.  If the count == 0 and the
1142  * @token matches that stored in the current task context, return to the
1143  * top level profile.
1144  *
1145  * change_hat only applies to profiles in the current ns, and each profile
1146  * in the ns must make the same transition otherwise change_hat will fail.
1147  */
1148 int aa_change_hat(const char *hats[], int count, u64 token, int flags)
1149 {
1150     const struct cred *cred;
1151     struct aa_task_ctx *ctx = task_ctx(current);
1152     struct aa_label *label, *previous, *new = NULL, *target = NULL;
1153     struct aa_profile *profile;
1154     struct aa_perms perms = {};
1155     const char *info = NULL;
1156     int error = 0;
1157 
1158     /* released below */
1159     cred = get_current_cred();
1160     label = aa_get_newest_cred_label(cred);
1161     previous = aa_get_newest_label(ctx->previous);
1162 
1163     /*
1164      * Detect no new privs being set, and store the label it
1165      * occurred under. Ideally this would happen when nnp
1166      * is set but there isn't a good way to do that yet.
1167      *
1168      * Testing for unconfined must be done before the subset test
1169      */
1170     if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1171         ctx->nnp = aa_get_label(label);
1172 
1173     if (unconfined(label)) {
1174         info = "unconfined can not change_hat";
1175         error = -EPERM;
1176         goto fail;
1177     }
1178 
1179     if (count) {
1180         new = change_hat(label, hats, count, flags);
1181         AA_BUG(!new);
1182         if (IS_ERR(new)) {
1183             error = PTR_ERR(new);
1184             new = NULL;
1185             /* already audited */
1186             goto out;
1187         }
1188 
1189         error = may_change_ptraced_domain(new, &info);
1190         if (error)
1191             goto fail;
1192 
1193         /*
1194          * no new privs prevents domain transitions that would
1195          * reduce restrictions.
1196          */
1197         if (task_no_new_privs(current) && !unconfined(label) &&
1198             !aa_label_is_unconfined_subset(new, ctx->nnp)) {
1199             /* not an apparmor denial per se, so don't log it */
1200             AA_DEBUG("no_new_privs - change_hat denied");
1201             error = -EPERM;
1202             goto out;
1203         }
1204 
1205         if (flags & AA_CHANGE_TEST)
1206             goto out;
1207 
1208         target = new;
1209         error = aa_set_current_hat(new, token);
1210         if (error == -EACCES)
1211             /* kill task in case of brute force attacks */
1212             goto kill;
1213     } else if (previous && !(flags & AA_CHANGE_TEST)) {
1214         /*
1215          * no new privs prevents domain transitions that would
1216          * reduce restrictions.
1217          */
1218         if (task_no_new_privs(current) && !unconfined(label) &&
1219             !aa_label_is_unconfined_subset(previous, ctx->nnp)) {
1220             /* not an apparmor denial per se, so don't log it */
1221             AA_DEBUG("no_new_privs - change_hat denied");
1222             error = -EPERM;
1223             goto out;
1224         }
1225 
1226         /* Return to saved label.  Kill task if restore fails
1227          * to avoid brute force attacks
1228          */
1229         target = previous;
1230         error = aa_restore_previous_label(token);
1231         if (error) {
1232             if (error == -EACCES)
1233                 goto kill;
1234             goto fail;
1235         }
1236     } /* else ignore @flags && restores when there is no saved profile */
1237 
1238 out:
1239     aa_put_label(new);
1240     aa_put_label(previous);
1241     aa_put_label(label);
1242     put_cred(cred);
1243 
1244     return error;
1245 
1246 kill:
1247     info = "failed token match";
1248     perms.kill = AA_MAY_CHANGEHAT;
1249 
1250 fail:
1251     fn_for_each_in_ns(label, profile,
1252         aa_audit_file(profile, &perms, OP_CHANGE_HAT,
1253                   AA_MAY_CHANGEHAT, NULL, NULL, target,
1254                   GLOBAL_ROOT_UID, info, error));
1255 
1256     goto out;
1257 }
1258 
1259 
1260 static int change_profile_perms_wrapper(const char *op, const char *name,
1261                     struct aa_profile *profile,
1262                     struct aa_label *target, bool stack,
1263                     u32 request, struct aa_perms *perms)
1264 {
1265     const char *info = NULL;
1266     int error = 0;
1267 
1268     if (!error)
1269         error = change_profile_perms(profile, target, stack, request,
1270                          profile->file.start, perms);
1271     if (error)
1272         error = aa_audit_file(profile, perms, op, request, name,
1273                       NULL, target, GLOBAL_ROOT_UID, info,
1274                       error);
1275 
1276     return error;
1277 }
1278 
1279 /**
1280  * aa_change_profile - perform a one-way profile transition
1281  * @fqname: name of profile may include namespace (NOT NULL)
1282  * @flags: flags affecting change behavior
1283  *
1284  * Change to new profile @name.  Unlike with hats, there is no way
1285  * to change back.  If @name isn't specified the current profile name is
1286  * used.
1287  * If @onexec then the transition is delayed until
1288  * the next exec.
1289  *
1290  * Returns %0 on success, error otherwise.
1291  */
1292 int aa_change_profile(const char *fqname, int flags)
1293 {
1294     struct aa_label *label, *new = NULL, *target = NULL;
1295     struct aa_profile *profile;
1296     struct aa_perms perms = {};
1297     const char *info = NULL;
1298     const char *auditname = fqname;     /* retain leading & if stack */
1299     bool stack = flags & AA_CHANGE_STACK;
1300     struct aa_task_ctx *ctx = task_ctx(current);
1301     int error = 0;
1302     char *op;
1303     u32 request;
1304 
1305     label = aa_get_current_label();
1306 
1307     /*
1308      * Detect no new privs being set, and store the label it
1309      * occurred under. Ideally this would happen when nnp
1310      * is set but there isn't a good way to do that yet.
1311      *
1312      * Testing for unconfined must be done before the subset test
1313      */
1314     if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1315         ctx->nnp = aa_get_label(label);
1316 
1317     if (!fqname || !*fqname) {
1318         aa_put_label(label);
1319         AA_DEBUG("no profile name");
1320         return -EINVAL;
1321     }
1322 
1323     if (flags & AA_CHANGE_ONEXEC) {
1324         request = AA_MAY_ONEXEC;
1325         if (stack)
1326             op = OP_STACK_ONEXEC;
1327         else
1328             op = OP_CHANGE_ONEXEC;
1329     } else {
1330         request = AA_MAY_CHANGE_PROFILE;
1331         if (stack)
1332             op = OP_STACK;
1333         else
1334             op = OP_CHANGE_PROFILE;
1335     }
1336 
1337     if (*fqname == '&') {
1338         stack = true;
1339         /* don't have label_parse() do stacking */
1340         fqname++;
1341     }
1342     target = aa_label_parse(label, fqname, GFP_KERNEL, true, false);
1343     if (IS_ERR(target)) {
1344         struct aa_profile *tprofile;
1345 
1346         info = "label not found";
1347         error = PTR_ERR(target);
1348         target = NULL;
1349         /*
1350          * TODO: fixme using labels_profile is not right - do profile
1351          * per complain profile
1352          */
1353         if ((flags & AA_CHANGE_TEST) ||
1354             !COMPLAIN_MODE(labels_profile(label)))
1355             goto audit;
1356         /* released below */
1357         tprofile = aa_new_null_profile(labels_profile(label), false,
1358                            fqname, GFP_KERNEL);
1359         if (!tprofile) {
1360             info = "failed null profile create";
1361             error = -ENOMEM;
1362             goto audit;
1363         }
1364         target = &tprofile->label;
1365         goto check;
1366     }
1367 
1368     /*
1369      * self directed transitions only apply to current policy ns
1370      * TODO: currently requiring perms for stacking and straight change
1371      *       stacking doesn't strictly need this. Determine how much
1372      *       we want to loosen this restriction for stacking
1373      *
1374      * if (!stack) {
1375      */
1376     error = fn_for_each_in_ns(label, profile,
1377             change_profile_perms_wrapper(op, auditname,
1378                              profile, target, stack,
1379                              request, &perms));
1380     if (error)
1381         /* auditing done in change_profile_perms_wrapper */
1382         goto out;
1383 
1384     /* } */
1385 
1386 check:
1387     /* check if tracing task is allowed to trace target domain */
1388     error = may_change_ptraced_domain(target, &info);
1389     if (error && !fn_for_each_in_ns(label, profile,
1390                     COMPLAIN_MODE(profile)))
1391         goto audit;
1392 
1393     /* TODO: add permission check to allow this
1394      * if ((flags & AA_CHANGE_ONEXEC) && !current_is_single_threaded()) {
1395      *      info = "not a single threaded task";
1396      *      error = -EACCES;
1397      *      goto audit;
1398      * }
1399      */
1400     if (flags & AA_CHANGE_TEST)
1401         goto out;
1402 
1403     /* stacking is always a subset, so only check the nonstack case */
1404     if (!stack) {
1405         new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1406                        aa_get_label(target),
1407                        aa_get_label(&profile->label));
1408         /*
1409          * no new privs prevents domain transitions that would
1410          * reduce restrictions.
1411          */
1412         if (task_no_new_privs(current) && !unconfined(label) &&
1413             !aa_label_is_unconfined_subset(new, ctx->nnp)) {
1414             /* not an apparmor denial per se, so don't log it */
1415             AA_DEBUG("no_new_privs - change_hat denied");
1416             error = -EPERM;
1417             goto out;
1418         }
1419     }
1420 
1421     if (!(flags & AA_CHANGE_ONEXEC)) {
1422         /* only transition profiles in the current ns */
1423         if (stack)
1424             new = aa_label_merge(label, target, GFP_KERNEL);
1425         if (IS_ERR_OR_NULL(new)) {
1426             info = "failed to build target label";
1427             if (!new)
1428                 error = -ENOMEM;
1429             else
1430                 error = PTR_ERR(new);
1431             new = NULL;
1432             perms.allow = 0;
1433             goto audit;
1434         }
1435         error = aa_replace_current_label(new);
1436     } else {
1437         if (new) {
1438             aa_put_label(new);
1439             new = NULL;
1440         }
1441 
1442         /* full transition will be built in exec path */
1443         error = aa_set_current_onexec(target, stack);
1444     }
1445 
1446 audit:
1447     error = fn_for_each_in_ns(label, profile,
1448             aa_audit_file(profile, &perms, op, request, auditname,
1449                       NULL, new ? new : target,
1450                       GLOBAL_ROOT_UID, info, error));
1451 
1452 out:
1453     aa_put_label(new);
1454     aa_put_label(target);
1455     aa_put_label(label);
1456 
1457     return error;
1458 }