Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

apparmor: fix x_table_lookup when stacking is not the first entry

x_table_lookup currently does stacking during label_parse() if the
target specifies a stack but its only caller ensures that it will
never be used with stacking.

Refactor to slightly simplify the code in x_to_label(), this
also fixes a long standing problem where x_to_labels check on stacking
is only on the first element to the table option list, instead of
the element that is found and used.

Signed-off-by: John Johansen <john.johansen@canonical.com>

+29 -23
+29 -23
security/apparmor/domain.c
··· 509 509 * @name: returns: name tested to find label (NOT NULL) 510 510 * 511 511 * Returns: refcounted label, or NULL on failure (MAYBE NULL) 512 + * @name will always be set with the last name tried 512 513 */ 513 514 struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, 514 515 const char **name) ··· 519 518 struct aa_label *label = NULL; 520 519 u32 xtype = xindex & AA_X_TYPE_MASK; 521 520 int index = xindex & AA_X_INDEX_MASK; 521 + const char *next; 522 522 523 523 AA_BUG(!name); 524 524 ··· 527 525 /* TODO: move lookup parsing to unpack time so this is a straight 528 526 * index into the resultant label 529 527 */ 530 - for (*name = rules->file->trans.table[index]; !label && *name; 531 - *name = next_name(xtype, *name)) { 528 + for (next = rules->file->trans.table[index]; next; 529 + next = next_name(xtype, next)) { 530 + const char *lookup = (*next == '&') ? next + 1 : next; 531 + *name = next; 532 532 if (xindex & AA_X_CHILD) { 533 - struct aa_profile *new_profile; 534 - /* release by caller */ 535 - new_profile = aa_find_child(profile, *name); 536 - if (new_profile) 537 - label = &new_profile->label; 533 + /* TODO: switich to parse to get stack of child */ 534 + struct aa_profile *new = aa_find_child(profile, lookup); 535 + 536 + if (new) 537 + /* release by caller */ 538 + return &new->label; 538 539 continue; 539 540 } 540 - label = aa_label_parse(&profile->label, *name, GFP_KERNEL, 541 + label = aa_label_parse(&profile->label, lookup, GFP_KERNEL, 541 542 true, false); 542 - if (IS_ERR(label)) 543 - label = NULL; 543 + if (!IS_ERR_OR_NULL(label)) 544 + /* release by caller */ 545 + return label; 544 546 } 545 547 546 - /* released by caller */ 547 - 548 - return label; 548 + return NULL; 549 549 } 550 550 551 551 /** ··· 572 568 struct aa_ruleset *rules = list_first_entry(&profile->rules, 573 569 typeof(*rules), list); 574 570 struct aa_label *new = NULL; 571 + struct aa_label *stack = NULL; 575 572 struct aa_ns *ns = profile->ns; 576 573 u32 xtype = xindex & AA_X_TYPE_MASK; 577 - const char *stack = NULL; 578 574 579 575 switch (xtype) { 580 576 case AA_X_NONE: ··· 583 579 break; 584 580 case AA_X_TABLE: 585 581 /* TODO: fix when perm mapping done at unload */ 586 - stack = rules->file->trans.table[xindex & AA_X_INDEX_MASK]; 587 - if (*stack != '&') { 588 - /* released by caller */ 589 - new = x_table_lookup(profile, xindex, lookupname); 590 - stack = NULL; 582 + /* released by caller 583 + * if null for both stack and direct want to try fallback 584 + */ 585 + new = x_table_lookup(profile, xindex, lookupname); 586 + if (!new || **lookupname != '&') 591 587 break; 592 - } 588 + stack = new; 589 + new = NULL; 593 590 fallthrough; /* to X_NAME */ 594 591 case AA_X_NAME: 595 592 if (xindex & AA_X_CHILD) ··· 605 600 break; 606 601 } 607 602 603 + /* fallback transition check */ 608 604 if (!new) { 609 605 if (xindex & AA_X_INHERIT) { 610 606 /* (p|c|n)ix - don't change profile but do ··· 624 618 /* base the stack on post domain transition */ 625 619 struct aa_label *base = new; 626 620 627 - new = aa_label_parse(base, stack, GFP_KERNEL, true, false); 628 - if (IS_ERR(new)) 629 - new = NULL; 621 + new = aa_label_merge(base, stack, GFP_KERNEL); 622 + /* null on error */ 630 623 aa_put_label(base); 631 624 } 632 625 626 + aa_put_label(stack); 633 627 /* released by caller */ 634 628 return new; 635 629 }