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