xref: /openbmc/linux/security/apparmor/domain.c (revision 20e2fc42)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AppArmor security module
4  *
5  * This file contains AppArmor policy attachment and domain transitions
6  *
7  * Copyright (C) 2002-2008 Novell/SUSE
8  * Copyright 2009-2010 Canonical Ltd.
9  */
10 
11 #include <linux/errno.h>
12 #include <linux/fdtable.h>
13 #include <linux/file.h>
14 #include <linux/mount.h>
15 #include <linux/syscalls.h>
16 #include <linux/tracehook.h>
17 #include <linux/personality.h>
18 #include <linux/xattr.h>
19 
20 #include "include/audit.h"
21 #include "include/apparmorfs.h"
22 #include "include/cred.h"
23 #include "include/domain.h"
24 #include "include/file.h"
25 #include "include/ipc.h"
26 #include "include/match.h"
27 #include "include/path.h"
28 #include "include/policy.h"
29 #include "include/policy_ns.h"
30 
31 /**
32  * aa_free_domain_entries - free entries in a domain table
33  * @domain: the domain table to free  (MAYBE NULL)
34  */
35 void aa_free_domain_entries(struct aa_domain *domain)
36 {
37 	int i;
38 	if (domain) {
39 		if (!domain->table)
40 			return;
41 
42 		for (i = 0; i < domain->size; i++)
43 			kzfree(domain->table[i]);
44 		kzfree(domain->table);
45 		domain->table = NULL;
46 	}
47 }
48 
49 /**
50  * may_change_ptraced_domain - check if can change profile on ptraced task
51  * @to_label: profile to change to  (NOT NULL)
52  * @info: message if there is an error
53  *
54  * Check if current is ptraced and if so if the tracing task is allowed
55  * to trace the new domain
56  *
57  * Returns: %0 or error if change not allowed
58  */
59 static int may_change_ptraced_domain(struct aa_label *to_label,
60 				     const char **info)
61 {
62 	struct task_struct *tracer;
63 	struct aa_label *tracerl = NULL;
64 	int error = 0;
65 
66 	rcu_read_lock();
67 	tracer = ptrace_parent(current);
68 	if (tracer)
69 		/* released below */
70 		tracerl = aa_get_task_label(tracer);
71 
72 	/* not ptraced */
73 	if (!tracer || unconfined(tracerl))
74 		goto out;
75 
76 	error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
77 
78 out:
79 	rcu_read_unlock();
80 	aa_put_label(tracerl);
81 
82 	if (error)
83 		*info = "ptrace prevents transition";
84 	return error;
85 }
86 
87 /**** TODO: dedup to aa_label_match - needs perm and dfa, merging
88  * specifically this is an exact copy of aa_label_match except
89  * aa_compute_perms is replaced with aa_compute_fperms
90  * and policy.dfa with file.dfa
91  ****/
92 /* match a profile and its associated ns component if needed
93  * Assumes visibility test has already been done.
94  * If a subns profile is not to be matched should be prescreened with
95  * visibility test.
96  */
97 static inline unsigned int match_component(struct aa_profile *profile,
98 					   struct aa_profile *tp,
99 					   bool stack, unsigned int state)
100 {
101 	const char *ns_name;
102 
103 	if (stack)
104 		state = aa_dfa_match(profile->file.dfa, state, "&");
105 	if (profile->ns == tp->ns)
106 		return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
107 
108 	/* try matching with namespace name and then profile */
109 	ns_name = aa_ns_name(profile->ns, tp->ns, true);
110 	state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
111 	state = aa_dfa_match(profile->file.dfa, state, ns_name);
112 	state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
113 	return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
114 }
115 
116 /**
117  * label_compound_match - find perms for full compound label
118  * @profile: profile to find perms for
119  * @label: label to check access permissions for
120  * @stack: whether this is a stacking request
121  * @start: state to start match in
122  * @subns: whether to do permission checks on components in a subns
123  * @request: permissions to request
124  * @perms: perms struct to set
125  *
126  * Returns: 0 on success else ERROR
127  *
128  * For the label A//&B//&C this does the perm match for A//&B//&C
129  * @perms should be preinitialized with allperms OR a previous permission
130  *        check to be stacked.
131  */
132 static int label_compound_match(struct aa_profile *profile,
133 				struct aa_label *label, bool stack,
134 				unsigned int state, bool subns, u32 request,
135 				struct aa_perms *perms)
136 {
137 	struct aa_profile *tp;
138 	struct label_it i;
139 	struct path_cond cond = { };
140 
141 	/* find first subcomponent that is visible */
142 	label_for_each(i, label, tp) {
143 		if (!aa_ns_visible(profile->ns, tp->ns, subns))
144 			continue;
145 		state = match_component(profile, tp, stack, state);
146 		if (!state)
147 			goto fail;
148 		goto next;
149 	}
150 
151 	/* no component visible */
152 	*perms = allperms;
153 	return 0;
154 
155 next:
156 	label_for_each_cont(i, label, tp) {
157 		if (!aa_ns_visible(profile->ns, tp->ns, subns))
158 			continue;
159 		state = aa_dfa_match(profile->file.dfa, state, "//&");
160 		state = match_component(profile, tp, false, state);
161 		if (!state)
162 			goto fail;
163 	}
164 	*perms = aa_compute_fperms(profile->file.dfa, state, &cond);
165 	aa_apply_modes_to_perms(profile, perms);
166 	if ((perms->allow & request) != request)
167 		return -EACCES;
168 
169 	return 0;
170 
171 fail:
172 	*perms = nullperms;
173 	return -EACCES;
174 }
175 
176 /**
177  * label_components_match - find perms for all subcomponents of a label
178  * @profile: profile to find perms for
179  * @label: label to check access permissions for
180  * @stack: whether this is a stacking request
181  * @start: state to start match in
182  * @subns: whether to do permission checks on components in a subns
183  * @request: permissions to request
184  * @perms: an initialized perms struct to add accumulation to
185  *
186  * Returns: 0 on success else ERROR
187  *
188  * For the label A//&B//&C this does the perm match for each of A and B and C
189  * @perms should be preinitialized with allperms OR a previous permission
190  *        check to be stacked.
191  */
192 static int label_components_match(struct aa_profile *profile,
193 				  struct aa_label *label, bool stack,
194 				  unsigned int start, bool subns, u32 request,
195 				  struct aa_perms *perms)
196 {
197 	struct aa_profile *tp;
198 	struct label_it i;
199 	struct aa_perms tmp;
200 	struct path_cond cond = { };
201 	unsigned int state = 0;
202 
203 	/* find first subcomponent to test */
204 	label_for_each(i, label, tp) {
205 		if (!aa_ns_visible(profile->ns, tp->ns, subns))
206 			continue;
207 		state = match_component(profile, tp, stack, start);
208 		if (!state)
209 			goto fail;
210 		goto next;
211 	}
212 
213 	/* no subcomponents visible - no change in perms */
214 	return 0;
215 
216 next:
217 	tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
218 	aa_apply_modes_to_perms(profile, &tmp);
219 	aa_perms_accum(perms, &tmp);
220 	label_for_each_cont(i, label, tp) {
221 		if (!aa_ns_visible(profile->ns, tp->ns, subns))
222 			continue;
223 		state = match_component(profile, tp, stack, start);
224 		if (!state)
225 			goto fail;
226 		tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
227 		aa_apply_modes_to_perms(profile, &tmp);
228 		aa_perms_accum(perms, &tmp);
229 	}
230 
231 	if ((perms->allow & request) != request)
232 		return -EACCES;
233 
234 	return 0;
235 
236 fail:
237 	*perms = nullperms;
238 	return -EACCES;
239 }
240 
241 /**
242  * label_match - do a multi-component label match
243  * @profile: profile to match against (NOT NULL)
244  * @label: label to match (NOT NULL)
245  * @stack: whether this is a stacking request
246  * @state: state to start in
247  * @subns: whether to match subns components
248  * @request: permission request
249  * @perms: Returns computed perms (NOT NULL)
250  *
251  * Returns: the state the match finished in, may be the none matching state
252  */
253 static int label_match(struct aa_profile *profile, struct aa_label *label,
254 		       bool stack, unsigned int state, bool subns, u32 request,
255 		       struct aa_perms *perms)
256 {
257 	int error;
258 
259 	*perms = nullperms;
260 	error = label_compound_match(profile, label, stack, state, subns,
261 				     request, perms);
262 	if (!error)
263 		return error;
264 
265 	*perms = allperms;
266 	return label_components_match(profile, label, stack, state, subns,
267 				      request, perms);
268 }
269 
270 /******* end TODO: dedup *****/
271 
272 /**
273  * change_profile_perms - find permissions for change_profile
274  * @profile: the current profile  (NOT NULL)
275  * @target: label to transition to (NOT NULL)
276  * @stack: whether this is a stacking request
277  * @request: requested perms
278  * @start: state to start matching in
279  *
280  *
281  * Returns: permission set
282  *
283  * currently only matches full label A//&B//&C or individual components A, B, C
284  * not arbitrary combinations. Eg. A//&B, C
285  */
286 static int change_profile_perms(struct aa_profile *profile,
287 				struct aa_label *target, bool stack,
288 				u32 request, unsigned int start,
289 				struct aa_perms *perms)
290 {
291 	if (profile_unconfined(profile)) {
292 		perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
293 		perms->audit = perms->quiet = perms->kill = 0;
294 		return 0;
295 	}
296 
297 	/* TODO: add profile in ns screening */
298 	return label_match(profile, target, stack, start, true, request, perms);
299 }
300 
301 /**
302  * aa_xattrs_match - check whether a file matches the xattrs defined in profile
303  * @bprm: binprm struct for the process to validate
304  * @profile: profile to match against (NOT NULL)
305  * @state: state to start match in
306  *
307  * Returns: number of extended attributes that matched, or < 0 on error
308  */
309 static int aa_xattrs_match(const struct linux_binprm *bprm,
310 			   struct aa_profile *profile, unsigned int state)
311 {
312 	int i;
313 	ssize_t size;
314 	struct dentry *d;
315 	char *value = NULL;
316 	int value_size = 0, ret = profile->xattr_count;
317 
318 	if (!bprm || !profile->xattr_count)
319 		return 0;
320 
321 	/* transition from exec match to xattr set */
322 	state = aa_dfa_null_transition(profile->xmatch, state);
323 
324 	d = bprm->file->f_path.dentry;
325 
326 	for (i = 0; i < profile->xattr_count; i++) {
327 		size = vfs_getxattr_alloc(d, profile->xattrs[i], &value,
328 					  value_size, GFP_KERNEL);
329 		if (size >= 0) {
330 			u32 perm;
331 
332 			/* Check the xattr value, not just presence */
333 			state = aa_dfa_match_len(profile->xmatch, state, value,
334 						 size);
335 			perm = dfa_user_allow(profile->xmatch, state);
336 			if (!(perm & MAY_EXEC)) {
337 				ret = -EINVAL;
338 				goto out;
339 			}
340 		}
341 		/* transition to next element */
342 		state = aa_dfa_null_transition(profile->xmatch, state);
343 		if (size < 0) {
344 			/*
345 			 * No xattr match, so verify if transition to
346 			 * next element was valid. IFF so the xattr
347 			 * was optional.
348 			 */
349 			if (!state) {
350 				ret = -EINVAL;
351 				goto out;
352 			}
353 			/* don't count missing optional xattr as matched */
354 			ret--;
355 		}
356 	}
357 
358 out:
359 	kfree(value);
360 	return ret;
361 }
362 
363 /**
364  * __attach_match_ - find an attachment match
365  * @bprm - binprm structure of transitioning task
366  * @name - to match against  (NOT NULL)
367  * @head - profile list to walk  (NOT NULL)
368  * @info - info message if there was an error (NOT NULL)
369  *
370  * Do a linear search on the profiles in the list.  There is a matching
371  * preference where an exact match is preferred over a name which uses
372  * expressions to match, and matching expressions with the greatest
373  * xmatch_len are preferred.
374  *
375  * Requires: @head not be shared or have appropriate locks held
376  *
377  * Returns: profile or NULL if no match found
378  */
379 static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
380 					 const char *name,
381 					 struct list_head *head,
382 					 const char **info)
383 {
384 	int candidate_len = 0, candidate_xattrs = 0;
385 	bool conflict = false;
386 	struct aa_profile *profile, *candidate = NULL;
387 
388 	AA_BUG(!name);
389 	AA_BUG(!head);
390 
391 	list_for_each_entry_rcu(profile, head, base.list) {
392 		if (profile->label.flags & FLAG_NULL &&
393 		    &profile->label == ns_unconfined(profile->ns))
394 			continue;
395 
396 		/* Find the "best" matching profile. Profiles must
397 		 * match the path and extended attributes (if any)
398 		 * associated with the file. A more specific path
399 		 * match will be preferred over a less specific one,
400 		 * and a match with more matching extended attributes
401 		 * will be preferred over one with fewer. If the best
402 		 * match has both the same level of path specificity
403 		 * and the same number of matching extended attributes
404 		 * as another profile, signal a conflict and refuse to
405 		 * match.
406 		 */
407 		if (profile->xmatch) {
408 			unsigned int state, count;
409 			u32 perm;
410 
411 			state = aa_dfa_leftmatch(profile->xmatch, DFA_START,
412 						 name, &count);
413 			perm = dfa_user_allow(profile->xmatch, state);
414 			/* any accepting state means a valid match. */
415 			if (perm & MAY_EXEC) {
416 				int ret;
417 
418 				if (count < candidate_len)
419 					continue;
420 
421 				ret = aa_xattrs_match(bprm, profile, state);
422 				/* Fail matching if the xattrs don't match */
423 				if (ret < 0)
424 					continue;
425 
426 				/*
427 				 * TODO: allow for more flexible best match
428 				 *
429 				 * The new match isn't more specific
430 				 * than the current best match
431 				 */
432 				if (count == candidate_len &&
433 				    ret <= candidate_xattrs) {
434 					/* Match is equivalent, so conflict */
435 					if (ret == candidate_xattrs)
436 						conflict = true;
437 					continue;
438 				}
439 
440 				/* Either the same length with more matching
441 				 * xattrs, or a longer match
442 				 */
443 				candidate = profile;
444 				candidate_len = profile->xmatch_len;
445 				candidate_xattrs = ret;
446 				conflict = false;
447 			}
448 		} else if (!strcmp(profile->base.name, name))
449 			/*
450 			 * old exact non-re match, without conditionals such
451 			 * as xattrs. no more searching required
452 			 */
453 			return profile;
454 	}
455 
456 	if (conflict) {
457 		*info = "conflicting profile attachments";
458 		return NULL;
459 	}
460 
461 	return candidate;
462 }
463 
464 /**
465  * find_attach - do attachment search for unconfined processes
466  * @bprm - binprm structure of transitioning task
467  * @ns: the current namespace  (NOT NULL)
468  * @list: list to search  (NOT NULL)
469  * @name: the executable name to match against  (NOT NULL)
470  * @info: info message if there was an error
471  *
472  * Returns: label or NULL if no match found
473  */
474 static struct aa_label *find_attach(const struct linux_binprm *bprm,
475 				    struct aa_ns *ns, struct list_head *list,
476 				    const char *name, const char **info)
477 {
478 	struct aa_profile *profile;
479 
480 	rcu_read_lock();
481 	profile = aa_get_profile(__attach_match(bprm, name, list, info));
482 	rcu_read_unlock();
483 
484 	return profile ? &profile->label : NULL;
485 }
486 
487 static const char *next_name(int xtype, const char *name)
488 {
489 	return NULL;
490 }
491 
492 /**
493  * x_table_lookup - lookup an x transition name via transition table
494  * @profile: current profile (NOT NULL)
495  * @xindex: index into x transition table
496  * @name: returns: name tested to find label (NOT NULL)
497  *
498  * Returns: refcounted label, or NULL on failure (MAYBE NULL)
499  */
500 struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
501 				const char **name)
502 {
503 	struct aa_label *label = NULL;
504 	u32 xtype = xindex & AA_X_TYPE_MASK;
505 	int index = xindex & AA_X_INDEX_MASK;
506 
507 	AA_BUG(!name);
508 
509 	/* index is guaranteed to be in range, validated at load time */
510 	/* TODO: move lookup parsing to unpack time so this is a straight
511 	 *       index into the resultant label
512 	 */
513 	for (*name = profile->file.trans.table[index]; !label && *name;
514 	     *name = next_name(xtype, *name)) {
515 		if (xindex & AA_X_CHILD) {
516 			struct aa_profile *new_profile;
517 			/* release by caller */
518 			new_profile = aa_find_child(profile, *name);
519 			if (new_profile)
520 				label = &new_profile->label;
521 			continue;
522 		}
523 		label = aa_label_parse(&profile->label, *name, GFP_ATOMIC,
524 				       true, false);
525 		if (IS_ERR(label))
526 			label = NULL;
527 	}
528 
529 	/* released by caller */
530 
531 	return label;
532 }
533 
534 /**
535  * x_to_label - get target label for a given xindex
536  * @profile: current profile  (NOT NULL)
537  * @bprm: binprm structure of transitioning task
538  * @name: name to lookup (NOT NULL)
539  * @xindex: index into x transition table
540  * @lookupname: returns: name used in lookup if one was specified (NOT NULL)
541  *
542  * find label for a transition index
543  *
544  * Returns: refcounted label or NULL if not found available
545  */
546 static struct aa_label *x_to_label(struct aa_profile *profile,
547 				   const struct linux_binprm *bprm,
548 				   const char *name, u32 xindex,
549 				   const char **lookupname,
550 				   const char **info)
551 {
552 	struct aa_label *new = NULL;
553 	struct aa_ns *ns = profile->ns;
554 	u32 xtype = xindex & AA_X_TYPE_MASK;
555 	const char *stack = NULL;
556 
557 	switch (xtype) {
558 	case AA_X_NONE:
559 		/* fail exec unless ix || ux fallback - handled by caller */
560 		*lookupname = NULL;
561 		break;
562 	case AA_X_TABLE:
563 		/* TODO: fix when perm mapping done at unload */
564 		stack = profile->file.trans.table[xindex & AA_X_INDEX_MASK];
565 		if (*stack != '&') {
566 			/* released by caller */
567 			new = x_table_lookup(profile, xindex, lookupname);
568 			stack = NULL;
569 			break;
570 		}
571 		/* fall through - to X_NAME */
572 	case AA_X_NAME:
573 		if (xindex & AA_X_CHILD)
574 			/* released by caller */
575 			new = find_attach(bprm, ns, &profile->base.profiles,
576 					  name, info);
577 		else
578 			/* released by caller */
579 			new = find_attach(bprm, ns, &ns->base.profiles,
580 					  name, info);
581 		*lookupname = name;
582 		break;
583 	}
584 
585 	if (!new) {
586 		if (xindex & AA_X_INHERIT) {
587 			/* (p|c|n)ix - don't change profile but do
588 			 * use the newest version
589 			 */
590 			*info = "ix fallback";
591 			/* no profile && no error */
592 			new = aa_get_newest_label(&profile->label);
593 		} else if (xindex & AA_X_UNCONFINED) {
594 			new = aa_get_newest_label(ns_unconfined(profile->ns));
595 			*info = "ux fallback";
596 		}
597 	}
598 
599 	if (new && stack) {
600 		/* base the stack on post domain transition */
601 		struct aa_label *base = new;
602 
603 		new = aa_label_parse(base, stack, GFP_ATOMIC, true, false);
604 		if (IS_ERR(new))
605 			new = NULL;
606 		aa_put_label(base);
607 	}
608 
609 	/* released by caller */
610 	return new;
611 }
612 
613 static struct aa_label *profile_transition(struct aa_profile *profile,
614 					   const struct linux_binprm *bprm,
615 					   char *buffer, struct path_cond *cond,
616 					   bool *secure_exec)
617 {
618 	struct aa_label *new = NULL;
619 	struct aa_profile *component;
620 	struct label_it i;
621 	const char *info = NULL, *name = NULL, *target = NULL;
622 	unsigned int state = profile->file.start;
623 	struct aa_perms perms = {};
624 	bool nonewprivs = false;
625 	int error = 0;
626 
627 	AA_BUG(!profile);
628 	AA_BUG(!bprm);
629 	AA_BUG(!buffer);
630 
631 	error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
632 			     &name, &info, profile->disconnected);
633 	if (error) {
634 		if (profile_unconfined(profile) ||
635 		    (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
636 			AA_DEBUG("name lookup ix on error");
637 			error = 0;
638 			new = aa_get_newest_label(&profile->label);
639 		}
640 		name = bprm->filename;
641 		goto audit;
642 	}
643 
644 	if (profile_unconfined(profile)) {
645 		new = find_attach(bprm, profile->ns,
646 				  &profile->ns->base.profiles, name, &info);
647 		if (new) {
648 			AA_DEBUG("unconfined attached to new label");
649 			return new;
650 		}
651 		AA_DEBUG("unconfined exec no attachment");
652 		return aa_get_newest_label(&profile->label);
653 	}
654 
655 	/* find exec permissions for name */
656 	state = aa_str_perms(profile->file.dfa, state, name, cond, &perms);
657 	if (perms.allow & MAY_EXEC) {
658 		/* exec permission determine how to transition */
659 		new = x_to_label(profile, bprm, name, perms.xindex, &target,
660 				 &info);
661 		if (new && new->proxy == profile->label.proxy && info) {
662 			/* hack ix fallback - improve how this is detected */
663 			goto audit;
664 		} else if (!new) {
665 			error = -EACCES;
666 			info = "profile transition not found";
667 			/* remove MAY_EXEC to audit as failure */
668 			perms.allow &= ~MAY_EXEC;
669 		} else {
670 			/* verify that each component's xattr requirements are
671 			 * met, and fail execution otherwise
672 			 */
673 			label_for_each(i, new, component) {
674 				if (aa_xattrs_match(bprm, component, state) <
675 				    0) {
676 					error = -EACCES;
677 					info = "required xattrs not present";
678 					perms.allow &= ~MAY_EXEC;
679 					aa_put_label(new);
680 					new = NULL;
681 					goto audit;
682 				}
683 			}
684 		}
685 	} else if (COMPLAIN_MODE(profile)) {
686 		/* no exec permission - learning mode */
687 		struct aa_profile *new_profile = NULL;
688 		char *n = kstrdup(name, GFP_ATOMIC);
689 
690 		if (n) {
691 			/* name is ptr into buffer */
692 			long pos = name - buffer;
693 			/* break per cpu buffer hold */
694 			put_buffers(buffer);
695 			new_profile = aa_new_null_profile(profile, false, n,
696 							  GFP_KERNEL);
697 			get_buffers(buffer);
698 			name = buffer + pos;
699 			strcpy((char *)name, n);
700 			kfree(n);
701 		}
702 		if (!new_profile) {
703 			error = -ENOMEM;
704 			info = "could not create null profile";
705 		} else {
706 			error = -EACCES;
707 			new = &new_profile->label;
708 		}
709 		perms.xindex |= AA_X_UNSAFE;
710 	} else
711 		/* fail exec */
712 		error = -EACCES;
713 
714 	if (!new)
715 		goto audit;
716 
717 
718 	if (!(perms.xindex & AA_X_UNSAFE)) {
719 		if (DEBUG_ON) {
720 			dbg_printk("apparmor: scrubbing environment variables"
721 				   " for %s profile=", name);
722 			aa_label_printk(new, GFP_ATOMIC);
723 			dbg_printk("\n");
724 		}
725 		*secure_exec = true;
726 	}
727 
728 audit:
729 	aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new,
730 		      cond->uid, info, error);
731 	if (!new || nonewprivs) {
732 		aa_put_label(new);
733 		return ERR_PTR(error);
734 	}
735 
736 	return new;
737 }
738 
739 static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
740 			  bool stack, const struct linux_binprm *bprm,
741 			  char *buffer, struct path_cond *cond,
742 			  bool *secure_exec)
743 {
744 	unsigned int state = profile->file.start;
745 	struct aa_perms perms = {};
746 	const char *xname = NULL, *info = "change_profile onexec";
747 	int error = -EACCES;
748 
749 	AA_BUG(!profile);
750 	AA_BUG(!onexec);
751 	AA_BUG(!bprm);
752 	AA_BUG(!buffer);
753 
754 	if (profile_unconfined(profile)) {
755 		/* change_profile on exec already granted */
756 		/*
757 		 * NOTE: Domain transitions from unconfined are allowed
758 		 * even when no_new_privs is set because this aways results
759 		 * in a further reduction of permissions.
760 		 */
761 		return 0;
762 	}
763 
764 	error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
765 			     &xname, &info, profile->disconnected);
766 	if (error) {
767 		if (profile_unconfined(profile) ||
768 		    (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
769 			AA_DEBUG("name lookup ix on error");
770 			error = 0;
771 		}
772 		xname = bprm->filename;
773 		goto audit;
774 	}
775 
776 	/* find exec permissions for name */
777 	state = aa_str_perms(profile->file.dfa, state, xname, cond, &perms);
778 	if (!(perms.allow & AA_MAY_ONEXEC)) {
779 		info = "no change_onexec valid for executable";
780 		goto audit;
781 	}
782 	/* test if this exec can be paired with change_profile onexec.
783 	 * onexec permission is linked to exec with a standard pairing
784 	 * exec\0change_profile
785 	 */
786 	state = aa_dfa_null_transition(profile->file.dfa, state);
787 	error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC,
788 				     state, &perms);
789 	if (error) {
790 		perms.allow &= ~AA_MAY_ONEXEC;
791 		goto audit;
792 	}
793 
794 	if (!(perms.xindex & AA_X_UNSAFE)) {
795 		if (DEBUG_ON) {
796 			dbg_printk("apparmor: scrubbing environment "
797 				   "variables for %s label=", xname);
798 			aa_label_printk(onexec, GFP_ATOMIC);
799 			dbg_printk("\n");
800 		}
801 		*secure_exec = true;
802 	}
803 
804 audit:
805 	return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname,
806 			     NULL, onexec, cond->uid, info, error);
807 }
808 
809 /* ensure none ns domain transitions are correctly applied with onexec */
810 
811 static struct aa_label *handle_onexec(struct aa_label *label,
812 				      struct aa_label *onexec, bool stack,
813 				      const struct linux_binprm *bprm,
814 				      char *buffer, struct path_cond *cond,
815 				      bool *unsafe)
816 {
817 	struct aa_profile *profile;
818 	struct aa_label *new;
819 	int error;
820 
821 	AA_BUG(!label);
822 	AA_BUG(!onexec);
823 	AA_BUG(!bprm);
824 	AA_BUG(!buffer);
825 
826 	if (!stack) {
827 		error = fn_for_each_in_ns(label, profile,
828 				profile_onexec(profile, onexec, stack,
829 					       bprm, buffer, cond, unsafe));
830 		if (error)
831 			return ERR_PTR(error);
832 		new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
833 				aa_get_newest_label(onexec),
834 				profile_transition(profile, bprm, buffer,
835 						   cond, unsafe));
836 
837 	} else {
838 		/* TODO: determine how much we want to loosen this */
839 		error = fn_for_each_in_ns(label, profile,
840 				profile_onexec(profile, onexec, stack, bprm,
841 					       buffer, cond, unsafe));
842 		if (error)
843 			return ERR_PTR(error);
844 		new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
845 				aa_label_merge(&profile->label, onexec,
846 					       GFP_ATOMIC),
847 				profile_transition(profile, bprm, buffer,
848 						   cond, unsafe));
849 	}
850 
851 	if (new)
852 		return new;
853 
854 	/* TODO: get rid of GLOBAL_ROOT_UID */
855 	error = fn_for_each_in_ns(label, profile,
856 			aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC,
857 				      AA_MAY_ONEXEC, bprm->filename, NULL,
858 				      onexec, GLOBAL_ROOT_UID,
859 				      "failed to build target label", -ENOMEM));
860 	return ERR_PTR(error);
861 }
862 
863 /**
864  * apparmor_bprm_set_creds - set the new creds on the bprm struct
865  * @bprm: binprm for the exec  (NOT NULL)
866  *
867  * Returns: %0 or error on failure
868  *
869  * TODO: once the other paths are done see if we can't refactor into a fn
870  */
871 int apparmor_bprm_set_creds(struct linux_binprm *bprm)
872 {
873 	struct aa_task_ctx *ctx;
874 	struct aa_label *label, *new = NULL;
875 	struct aa_profile *profile;
876 	char *buffer = NULL;
877 	const char *info = NULL;
878 	int error = 0;
879 	bool unsafe = false;
880 	struct path_cond cond = {
881 		file_inode(bprm->file)->i_uid,
882 		file_inode(bprm->file)->i_mode
883 	};
884 
885 	if (bprm->called_set_creds)
886 		return 0;
887 
888 	ctx = task_ctx(current);
889 	AA_BUG(!cred_label(bprm->cred));
890 	AA_BUG(!ctx);
891 
892 	label = aa_get_newest_label(cred_label(bprm->cred));
893 
894 	/*
895 	 * Detect no new privs being set, and store the label it
896 	 * occurred under. Ideally this would happen when nnp
897 	 * is set but there isn't a good way to do that yet.
898 	 *
899 	 * Testing for unconfined must be done before the subset test
900 	 */
901 	if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) && !unconfined(label) &&
902 	    !ctx->nnp)
903 		ctx->nnp = aa_get_label(label);
904 
905 	/* buffer freed below, name is pointer into buffer */
906 	get_buffers(buffer);
907 	/* Test for onexec first as onexec override other x transitions. */
908 	if (ctx->onexec)
909 		new = handle_onexec(label, ctx->onexec, ctx->token,
910 				    bprm, buffer, &cond, &unsafe);
911 	else
912 		new = fn_label_build(label, profile, GFP_ATOMIC,
913 				profile_transition(profile, bprm, buffer,
914 						   &cond, &unsafe));
915 
916 	AA_BUG(!new);
917 	if (IS_ERR(new)) {
918 		error = PTR_ERR(new);
919 		goto done;
920 	} else if (!new) {
921 		error = -ENOMEM;
922 		goto done;
923 	}
924 
925 	/* Policy has specified a domain transitions. If no_new_privs and
926 	 * confined ensure the transition is to confinement that is subset
927 	 * of the confinement when the task entered no new privs.
928 	 *
929 	 * NOTE: Domain transitions from unconfined and to stacked
930 	 * subsets are allowed even when no_new_privs is set because this
931 	 * aways results in a further reduction of permissions.
932 	 */
933 	if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
934 	    !unconfined(label) && !aa_label_is_subset(new, ctx->nnp)) {
935 		error = -EPERM;
936 		info = "no new privs";
937 		goto audit;
938 	}
939 
940 	if (bprm->unsafe & LSM_UNSAFE_SHARE) {
941 		/* FIXME: currently don't mediate shared state */
942 		;
943 	}
944 
945 	if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) {
946 		/* TODO: test needs to be profile of label to new */
947 		error = may_change_ptraced_domain(new, &info);
948 		if (error)
949 			goto audit;
950 	}
951 
952 	if (unsafe) {
953 		if (DEBUG_ON) {
954 			dbg_printk("scrubbing environment variables for %s "
955 				   "label=", bprm->filename);
956 			aa_label_printk(new, GFP_ATOMIC);
957 			dbg_printk("\n");
958 		}
959 		bprm->secureexec = 1;
960 	}
961 
962 	if (label->proxy != new->proxy) {
963 		/* when transitioning clear unsafe personality bits */
964 		if (DEBUG_ON) {
965 			dbg_printk("apparmor: clearing unsafe personality "
966 				   "bits. %s label=", bprm->filename);
967 			aa_label_printk(new, GFP_ATOMIC);
968 			dbg_printk("\n");
969 		}
970 		bprm->per_clear |= PER_CLEAR_ON_SETID;
971 	}
972 	aa_put_label(cred_label(bprm->cred));
973 	/* transfer reference, released when cred is freed */
974 	set_cred_label(bprm->cred, new);
975 
976 done:
977 	aa_put_label(label);
978 	put_buffers(buffer);
979 
980 	return error;
981 
982 audit:
983 	error = fn_for_each(label, profile,
984 			aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC,
985 				      bprm->filename, NULL, new,
986 				      file_inode(bprm->file)->i_uid, info,
987 				      error));
988 	aa_put_label(new);
989 	goto done;
990 }
991 
992 /*
993  * Functions for self directed profile change
994  */
995 
996 
997 /* helper fn for change_hat
998  *
999  * Returns: label for hat transition OR ERR_PTR.  Does NOT return NULL
1000  */
1001 static struct aa_label *build_change_hat(struct aa_profile *profile,
1002 					 const char *name, bool sibling)
1003 {
1004 	struct aa_profile *root, *hat = NULL;
1005 	const char *info = NULL;
1006 	int error = 0;
1007 
1008 	if (sibling && PROFILE_IS_HAT(profile)) {
1009 		root = aa_get_profile_rcu(&profile->parent);
1010 	} else if (!sibling && !PROFILE_IS_HAT(profile)) {
1011 		root = aa_get_profile(profile);
1012 	} else {
1013 		info = "conflicting target types";
1014 		error = -EPERM;
1015 		goto audit;
1016 	}
1017 
1018 	hat = aa_find_child(root, name);
1019 	if (!hat) {
1020 		error = -ENOENT;
1021 		if (COMPLAIN_MODE(profile)) {
1022 			hat = aa_new_null_profile(profile, true, name,
1023 						  GFP_KERNEL);
1024 			if (!hat) {
1025 				info = "failed null profile create";
1026 				error = -ENOMEM;
1027 			}
1028 		}
1029 	}
1030 	aa_put_profile(root);
1031 
1032 audit:
1033 	aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
1034 		      name, hat ? hat->base.hname : NULL,
1035 		      hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
1036 		      error);
1037 	if (!hat || (error && error != -ENOENT))
1038 		return ERR_PTR(error);
1039 	/* if hat && error - complain mode, already audited and we adjust for
1040 	 * complain mode allow by returning hat->label
1041 	 */
1042 	return &hat->label;
1043 }
1044 
1045 /* helper fn for changing into a hat
1046  *
1047  * Returns: label for hat transition or ERR_PTR. Does not return NULL
1048  */
1049 static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
1050 				   int count, int flags)
1051 {
1052 	struct aa_profile *profile, *root, *hat = NULL;
1053 	struct aa_label *new;
1054 	struct label_it it;
1055 	bool sibling = false;
1056 	const char *name, *info = NULL;
1057 	int i, error;
1058 
1059 	AA_BUG(!label);
1060 	AA_BUG(!hats);
1061 	AA_BUG(count < 1);
1062 
1063 	if (PROFILE_IS_HAT(labels_profile(label)))
1064 		sibling = true;
1065 
1066 	/*find first matching hat */
1067 	for (i = 0; i < count && !hat; i++) {
1068 		name = hats[i];
1069 		label_for_each_in_ns(it, labels_ns(label), label, profile) {
1070 			if (sibling && PROFILE_IS_HAT(profile)) {
1071 				root = aa_get_profile_rcu(&profile->parent);
1072 			} else if (!sibling && !PROFILE_IS_HAT(profile)) {
1073 				root = aa_get_profile(profile);
1074 			} else {	/* conflicting change type */
1075 				info = "conflicting targets types";
1076 				error = -EPERM;
1077 				goto fail;
1078 			}
1079 			hat = aa_find_child(root, name);
1080 			aa_put_profile(root);
1081 			if (!hat) {
1082 				if (!COMPLAIN_MODE(profile))
1083 					goto outer_continue;
1084 				/* complain mode succeed as if hat */
1085 			} else if (!PROFILE_IS_HAT(hat)) {
1086 				info = "target not hat";
1087 				error = -EPERM;
1088 				aa_put_profile(hat);
1089 				goto fail;
1090 			}
1091 			aa_put_profile(hat);
1092 		}
1093 		/* found a hat for all profiles in ns */
1094 		goto build;
1095 outer_continue:
1096 	;
1097 	}
1098 	/* no hats that match, find appropriate error
1099 	 *
1100 	 * In complain mode audit of the failure is based off of the first
1101 	 * hat supplied.  This is done due how userspace interacts with
1102 	 * change_hat.
1103 	 */
1104 	name = NULL;
1105 	label_for_each_in_ns(it, labels_ns(label), label, profile) {
1106 		if (!list_empty(&profile->base.profiles)) {
1107 			info = "hat not found";
1108 			error = -ENOENT;
1109 			goto fail;
1110 		}
1111 	}
1112 	info = "no hats defined";
1113 	error = -ECHILD;
1114 
1115 fail:
1116 	label_for_each_in_ns(it, labels_ns(label), label, profile) {
1117 		/*
1118 		 * no target as it has failed to be found or built
1119 		 *
1120 		 * change_hat uses probing and should not log failures
1121 		 * related to missing hats
1122 		 */
1123 		/* TODO: get rid of GLOBAL_ROOT_UID */
1124 		if (count > 1 || COMPLAIN_MODE(profile)) {
1125 			aa_audit_file(profile, &nullperms, OP_CHANGE_HAT,
1126 				      AA_MAY_CHANGEHAT, name, NULL, NULL,
1127 				      GLOBAL_ROOT_UID, info, error);
1128 		}
1129 	}
1130 	return ERR_PTR(error);
1131 
1132 build:
1133 	new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1134 				   build_change_hat(profile, name, sibling),
1135 				   aa_get_label(&profile->label));
1136 	if (!new) {
1137 		info = "label build failed";
1138 		error = -ENOMEM;
1139 		goto fail;
1140 	} /* else if (IS_ERR) build_change_hat has logged error so return new */
1141 
1142 	return new;
1143 }
1144 
1145 /**
1146  * aa_change_hat - change hat to/from subprofile
1147  * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0)
1148  * @count: number of hat names in @hats
1149  * @token: magic value to validate the hat change
1150  * @flags: flags affecting behavior of the change
1151  *
1152  * Returns %0 on success, error otherwise.
1153  *
1154  * Change to the first profile specified in @hats that exists, and store
1155  * the @hat_magic in the current task context.  If the count == 0 and the
1156  * @token matches that stored in the current task context, return to the
1157  * top level profile.
1158  *
1159  * change_hat only applies to profiles in the current ns, and each profile
1160  * in the ns must make the same transition otherwise change_hat will fail.
1161  */
1162 int aa_change_hat(const char *hats[], int count, u64 token, int flags)
1163 {
1164 	const struct cred *cred;
1165 	struct aa_task_ctx *ctx = task_ctx(current);
1166 	struct aa_label *label, *previous, *new = NULL, *target = NULL;
1167 	struct aa_profile *profile;
1168 	struct aa_perms perms = {};
1169 	const char *info = NULL;
1170 	int error = 0;
1171 
1172 	/* released below */
1173 	cred = get_current_cred();
1174 	label = aa_get_newest_cred_label(cred);
1175 	previous = aa_get_newest_label(ctx->previous);
1176 
1177 	/*
1178 	 * Detect no new privs being set, and store the label it
1179 	 * occurred under. Ideally this would happen when nnp
1180 	 * is set but there isn't a good way to do that yet.
1181 	 *
1182 	 * Testing for unconfined must be done before the subset test
1183 	 */
1184 	if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1185 		ctx->nnp = aa_get_label(label);
1186 
1187 	if (unconfined(label)) {
1188 		info = "unconfined can not change_hat";
1189 		error = -EPERM;
1190 		goto fail;
1191 	}
1192 
1193 	if (count) {
1194 		new = change_hat(label, hats, count, flags);
1195 		AA_BUG(!new);
1196 		if (IS_ERR(new)) {
1197 			error = PTR_ERR(new);
1198 			new = NULL;
1199 			/* already audited */
1200 			goto out;
1201 		}
1202 
1203 		error = may_change_ptraced_domain(new, &info);
1204 		if (error)
1205 			goto fail;
1206 
1207 		/*
1208 		 * no new privs prevents domain transitions that would
1209 		 * reduce restrictions.
1210 		 */
1211 		if (task_no_new_privs(current) && !unconfined(label) &&
1212 		    !aa_label_is_subset(new, ctx->nnp)) {
1213 			/* not an apparmor denial per se, so don't log it */
1214 			AA_DEBUG("no_new_privs - change_hat denied");
1215 			error = -EPERM;
1216 			goto out;
1217 		}
1218 
1219 		if (flags & AA_CHANGE_TEST)
1220 			goto out;
1221 
1222 		target = new;
1223 		error = aa_set_current_hat(new, token);
1224 		if (error == -EACCES)
1225 			/* kill task in case of brute force attacks */
1226 			goto kill;
1227 	} else if (previous && !(flags & AA_CHANGE_TEST)) {
1228 		/*
1229 		 * no new privs prevents domain transitions that would
1230 		 * reduce restrictions.
1231 		 */
1232 		if (task_no_new_privs(current) && !unconfined(label) &&
1233 		    !aa_label_is_subset(previous, ctx->nnp)) {
1234 			/* not an apparmor denial per se, so don't log it */
1235 			AA_DEBUG("no_new_privs - change_hat denied");
1236 			error = -EPERM;
1237 			goto out;
1238 		}
1239 
1240 		/* Return to saved label.  Kill task if restore fails
1241 		 * to avoid brute force attacks
1242 		 */
1243 		target = previous;
1244 		error = aa_restore_previous_label(token);
1245 		if (error) {
1246 			if (error == -EACCES)
1247 				goto kill;
1248 			goto fail;
1249 		}
1250 	} /* else ignore @flags && restores when there is no saved profile */
1251 
1252 out:
1253 	aa_put_label(new);
1254 	aa_put_label(previous);
1255 	aa_put_label(label);
1256 	put_cred(cred);
1257 
1258 	return error;
1259 
1260 kill:
1261 	info = "failed token match";
1262 	perms.kill = AA_MAY_CHANGEHAT;
1263 
1264 fail:
1265 	fn_for_each_in_ns(label, profile,
1266 		aa_audit_file(profile, &perms, OP_CHANGE_HAT,
1267 			      AA_MAY_CHANGEHAT, NULL, NULL, target,
1268 			      GLOBAL_ROOT_UID, info, error));
1269 
1270 	goto out;
1271 }
1272 
1273 
1274 static int change_profile_perms_wrapper(const char *op, const char *name,
1275 					struct aa_profile *profile,
1276 					struct aa_label *target, bool stack,
1277 					u32 request, struct aa_perms *perms)
1278 {
1279 	const char *info = NULL;
1280 	int error = 0;
1281 
1282 	if (!error)
1283 		error = change_profile_perms(profile, target, stack, request,
1284 					     profile->file.start, perms);
1285 	if (error)
1286 		error = aa_audit_file(profile, perms, op, request, name,
1287 				      NULL, target, GLOBAL_ROOT_UID, info,
1288 				      error);
1289 
1290 	return error;
1291 }
1292 
1293 /**
1294  * aa_change_profile - perform a one-way profile transition
1295  * @fqname: name of profile may include namespace (NOT NULL)
1296  * @onexec: whether this transition is to take place immediately or at exec
1297  * @flags: flags affecting change behavior
1298  *
1299  * Change to new profile @name.  Unlike with hats, there is no way
1300  * to change back.  If @name isn't specified the current profile name is
1301  * used.
1302  * If @onexec then the transition is delayed until
1303  * the next exec.
1304  *
1305  * Returns %0 on success, error otherwise.
1306  */
1307 int aa_change_profile(const char *fqname, int flags)
1308 {
1309 	struct aa_label *label, *new = NULL, *target = NULL;
1310 	struct aa_profile *profile;
1311 	struct aa_perms perms = {};
1312 	const char *info = NULL;
1313 	const char *auditname = fqname;		/* retain leading & if stack */
1314 	bool stack = flags & AA_CHANGE_STACK;
1315 	struct aa_task_ctx *ctx = task_ctx(current);
1316 	int error = 0;
1317 	char *op;
1318 	u32 request;
1319 
1320 	label = aa_get_current_label();
1321 
1322 	/*
1323 	 * Detect no new privs being set, and store the label it
1324 	 * occurred under. Ideally this would happen when nnp
1325 	 * is set but there isn't a good way to do that yet.
1326 	 *
1327 	 * Testing for unconfined must be done before the subset test
1328 	 */
1329 	if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1330 		ctx->nnp = aa_get_label(label);
1331 
1332 	if (!fqname || !*fqname) {
1333 		AA_DEBUG("no profile name");
1334 		return -EINVAL;
1335 	}
1336 
1337 	if (flags & AA_CHANGE_ONEXEC) {
1338 		request = AA_MAY_ONEXEC;
1339 		if (stack)
1340 			op = OP_STACK_ONEXEC;
1341 		else
1342 			op = OP_CHANGE_ONEXEC;
1343 	} else {
1344 		request = AA_MAY_CHANGE_PROFILE;
1345 		if (stack)
1346 			op = OP_STACK;
1347 		else
1348 			op = OP_CHANGE_PROFILE;
1349 	}
1350 
1351 	label = aa_get_current_label();
1352 
1353 	if (*fqname == '&') {
1354 		stack = true;
1355 		/* don't have label_parse() do stacking */
1356 		fqname++;
1357 	}
1358 	target = aa_label_parse(label, fqname, GFP_KERNEL, true, false);
1359 	if (IS_ERR(target)) {
1360 		struct aa_profile *tprofile;
1361 
1362 		info = "label not found";
1363 		error = PTR_ERR(target);
1364 		target = NULL;
1365 		/*
1366 		 * TODO: fixme using labels_profile is not right - do profile
1367 		 * per complain profile
1368 		 */
1369 		if ((flags & AA_CHANGE_TEST) ||
1370 		    !COMPLAIN_MODE(labels_profile(label)))
1371 			goto audit;
1372 		/* released below */
1373 		tprofile = aa_new_null_profile(labels_profile(label), false,
1374 					       fqname, GFP_KERNEL);
1375 		if (!tprofile) {
1376 			info = "failed null profile create";
1377 			error = -ENOMEM;
1378 			goto audit;
1379 		}
1380 		target = &tprofile->label;
1381 		goto check;
1382 	}
1383 
1384 	/*
1385 	 * self directed transitions only apply to current policy ns
1386 	 * TODO: currently requiring perms for stacking and straight change
1387 	 *       stacking doesn't strictly need this. Determine how much
1388 	 *       we want to loosen this restriction for stacking
1389 	 *
1390 	 * if (!stack) {
1391 	 */
1392 	error = fn_for_each_in_ns(label, profile,
1393 			change_profile_perms_wrapper(op, auditname,
1394 						     profile, target, stack,
1395 						     request, &perms));
1396 	if (error)
1397 		/* auditing done in change_profile_perms_wrapper */
1398 		goto out;
1399 
1400 	/* } */
1401 
1402 check:
1403 	/* check if tracing task is allowed to trace target domain */
1404 	error = may_change_ptraced_domain(target, &info);
1405 	if (error && !fn_for_each_in_ns(label, profile,
1406 					COMPLAIN_MODE(profile)))
1407 		goto audit;
1408 
1409 	/* TODO: add permission check to allow this
1410 	 * if ((flags & AA_CHANGE_ONEXEC) && !current_is_single_threaded()) {
1411 	 *      info = "not a single threaded task";
1412 	 *      error = -EACCES;
1413 	 *      goto audit;
1414 	 * }
1415 	 */
1416 	if (flags & AA_CHANGE_TEST)
1417 		goto out;
1418 
1419 	/* stacking is always a subset, so only check the nonstack case */
1420 	if (!stack) {
1421 		new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1422 					   aa_get_label(target),
1423 					   aa_get_label(&profile->label));
1424 		/*
1425 		 * no new privs prevents domain transitions that would
1426 		 * reduce restrictions.
1427 		 */
1428 		if (task_no_new_privs(current) && !unconfined(label) &&
1429 		    !aa_label_is_subset(new, ctx->nnp)) {
1430 			/* not an apparmor denial per se, so don't log it */
1431 			AA_DEBUG("no_new_privs - change_hat denied");
1432 			error = -EPERM;
1433 			goto out;
1434 		}
1435 	}
1436 
1437 	if (!(flags & AA_CHANGE_ONEXEC)) {
1438 		/* only transition profiles in the current ns */
1439 		if (stack)
1440 			new = aa_label_merge(label, target, GFP_KERNEL);
1441 		if (IS_ERR_OR_NULL(new)) {
1442 			info = "failed to build target label";
1443 			if (!new)
1444 				error = -ENOMEM;
1445 			else
1446 				error = PTR_ERR(new);
1447 			new = NULL;
1448 			perms.allow = 0;
1449 			goto audit;
1450 		}
1451 		error = aa_replace_current_label(new);
1452 	} else {
1453 		if (new) {
1454 			aa_put_label(new);
1455 			new = NULL;
1456 		}
1457 
1458 		/* full transition will be built in exec path */
1459 		error = aa_set_current_onexec(target, stack);
1460 	}
1461 
1462 audit:
1463 	error = fn_for_each_in_ns(label, profile,
1464 			aa_audit_file(profile, &perms, op, request, auditname,
1465 				      NULL, new ? new : target,
1466 				      GLOBAL_ROOT_UID, info, error));
1467 
1468 out:
1469 	aa_put_label(new);
1470 	aa_put_label(target);
1471 	aa_put_label(label);
1472 
1473 	return error;
1474 }
1475