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