domain.c (cf797c0e5e312520b0b9f0367039fc0279a07a76) | domain.c (df8073c67fd8acb7e79f203ba4c0fa456bb82762) |
---|---|
1/* 2 * AppArmor security module 3 * 4 * This file contains AppArmor policy attachment and domain transitions 5 * 6 * Copyright (C) 2002-2008 Novell/SUSE 7 * Copyright 2009-2010 Canonical Ltd. 8 * --- 549 unchanged lines hidden (view full) --- 558 return name; 559} 560 561/** 562 * aa_change_hat - change hat to/from subprofile 563 * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0) 564 * @count: number of hat names in @hats 565 * @token: magic value to validate the hat change | 1/* 2 * AppArmor security module 3 * 4 * This file contains AppArmor policy attachment and domain transitions 5 * 6 * Copyright (C) 2002-2008 Novell/SUSE 7 * Copyright 2009-2010 Canonical Ltd. 8 * --- 549 unchanged lines hidden (view full) --- 558 return name; 559} 560 561/** 562 * aa_change_hat - change hat to/from subprofile 563 * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0) 564 * @count: number of hat names in @hats 565 * @token: magic value to validate the hat change |
566 * @permtest: true if this is just a permission test | 566 * @flags: flags affecting behavior of the change |
567 * 568 * Change to the first profile specified in @hats that exists, and store 569 * the @hat_magic in the current task context. If the count == 0 and the 570 * @token matches that stored in the current task context, return to the 571 * top level profile. 572 * 573 * Returns %0 on success, error otherwise. 574 */ | 567 * 568 * Change to the first profile specified in @hats that exists, and store 569 * the @hat_magic in the current task context. If the count == 0 and the 570 * @token matches that stored in the current task context, return to the 571 * top level profile. 572 * 573 * Returns %0 on success, error otherwise. 574 */ |
575int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | 575int aa_change_hat(const char *hats[], int count, u64 token, int flags) |
576{ 577 const struct cred *cred; 578 struct aa_task_ctx *ctx; 579 struct aa_profile *profile, *previous_profile, *hat = NULL; 580 char *name = NULL; 581 int i; 582 struct aa_perms perms = {}; 583 const char *target = NULL, *info = NULL; --- 27 unchanged lines hidden (view full) --- 611 else 612 root = aa_get_profile(profile); 613 614 /* find first matching hat */ 615 for (i = 0; i < count && !hat; i++) 616 /* released below */ 617 hat = aa_find_child(root, hats[i]); 618 if (!hat) { | 576{ 577 const struct cred *cred; 578 struct aa_task_ctx *ctx; 579 struct aa_profile *profile, *previous_profile, *hat = NULL; 580 char *name = NULL; 581 int i; 582 struct aa_perms perms = {}; 583 const char *target = NULL, *info = NULL; --- 27 unchanged lines hidden (view full) --- 611 else 612 root = aa_get_profile(profile); 613 614 /* find first matching hat */ 615 for (i = 0; i < count && !hat; i++) 616 /* released below */ 617 hat = aa_find_child(root, hats[i]); 618 if (!hat) { |
619 if (!COMPLAIN_MODE(root) || permtest) { | 619 if (!COMPLAIN_MODE(root) || (flags & AA_CHANGE_TEST)) { |
620 if (list_empty(&root->base.profiles)) 621 error = -ECHILD; 622 else 623 error = -ENOENT; 624 aa_put_profile(root); 625 goto out; 626 } 627 --- 30 unchanged lines hidden (view full) --- 658 659 error = may_change_ptraced_domain(hat); 660 if (error) { 661 info = "ptraced"; 662 error = -EPERM; 663 goto audit; 664 } 665 | 620 if (list_empty(&root->base.profiles)) 621 error = -ECHILD; 622 else 623 error = -ENOENT; 624 aa_put_profile(root); 625 goto out; 626 } 627 --- 30 unchanged lines hidden (view full) --- 658 659 error = may_change_ptraced_domain(hat); 660 if (error) { 661 info = "ptraced"; 662 error = -EPERM; 663 goto audit; 664 } 665 |
666 if (!permtest) { | 666 if (!(flags & AA_CHANGE_TEST)) { |
667 error = aa_set_current_hat(hat, token); 668 if (error == -EACCES) 669 /* kill task in case of brute force attacks */ 670 perms.kill = AA_MAY_CHANGEHAT; 671 else if (name && !error) 672 /* reset error for learning of new hats */ 673 error = -ENOENT; 674 } --- 4 unchanged lines hidden (view full) --- 679 target = previous_profile->base.hname; 680 error = aa_restore_previous_profile(token); 681 perms.kill = AA_MAY_CHANGEHAT; 682 } else 683 /* ignore restores when there is no saved profile */ 684 goto out; 685 686audit: | 667 error = aa_set_current_hat(hat, token); 668 if (error == -EACCES) 669 /* kill task in case of brute force attacks */ 670 perms.kill = AA_MAY_CHANGEHAT; 671 else if (name && !error) 672 /* reset error for learning of new hats */ 673 error = -ENOENT; 674 } --- 4 unchanged lines hidden (view full) --- 679 target = previous_profile->base.hname; 680 error = aa_restore_previous_profile(token); 681 perms.kill = AA_MAY_CHANGEHAT; 682 } else 683 /* ignore restores when there is no saved profile */ 684 goto out; 685 686audit: |
687 if (!permtest) | 687 if (!(flags & AA_CHANGE_TEST)) |
688 error = aa_audit_file(profile, &perms, OP_CHANGE_HAT, 689 AA_MAY_CHANGEHAT, NULL, target, 690 GLOBAL_ROOT_UID, info, error); 691 692out: 693 aa_put_profile(hat); 694 kfree(name); 695 aa_put_profile(profile); 696 aa_put_profile(previous_profile); 697 put_cred(cred); 698 699 return error; 700} 701 702/** 703 * aa_change_profile - perform a one-way profile transition 704 * @fqname: name of profile may include namespace (NOT NULL) 705 * @onexec: whether this transition is to take place immediately or at exec | 688 error = aa_audit_file(profile, &perms, OP_CHANGE_HAT, 689 AA_MAY_CHANGEHAT, NULL, target, 690 GLOBAL_ROOT_UID, info, error); 691 692out: 693 aa_put_profile(hat); 694 kfree(name); 695 aa_put_profile(profile); 696 aa_put_profile(previous_profile); 697 put_cred(cred); 698 699 return error; 700} 701 702/** 703 * aa_change_profile - perform a one-way profile transition 704 * @fqname: name of profile may include namespace (NOT NULL) 705 * @onexec: whether this transition is to take place immediately or at exec |
706 * @permtest: true if this is just a permission test | 706 * @flags: flags affecting change behavior |
707 * 708 * Change to new profile @name. Unlike with hats, there is no way 709 * to change back. If @name isn't specified the current profile name is 710 * used. 711 * If @onexec then the transition is delayed until 712 * the next exec. 713 * 714 * Returns %0 on success, error otherwise. 715 */ | 707 * 708 * Change to new profile @name. Unlike with hats, there is no way 709 * to change back. If @name isn't specified the current profile name is 710 * used. 711 * If @onexec then the transition is delayed until 712 * the next exec. 713 * 714 * Returns %0 on success, error otherwise. 715 */ |
716int aa_change_profile(const char *fqname, bool onexec, 717 bool permtest, bool stack) | 716int aa_change_profile(const char *fqname, int flags) |
718{ 719 const struct cred *cred; 720 struct aa_profile *profile, *target = NULL; 721 struct aa_perms perms = {}; 722 const char *info = NULL, *op; 723 int error = 0; 724 u32 request; 725 726 if (!fqname || !*fqname) { 727 AA_DEBUG("no profile name"); 728 return -EINVAL; 729 } 730 | 717{ 718 const struct cred *cred; 719 struct aa_profile *profile, *target = NULL; 720 struct aa_perms perms = {}; 721 const char *info = NULL, *op; 722 int error = 0; 723 u32 request; 724 725 if (!fqname || !*fqname) { 726 AA_DEBUG("no profile name"); 727 return -EINVAL; 728 } 729 |
731 if (onexec) { | 730 if (flags & AA_CHANGE_ONEXEC) { |
732 request = AA_MAY_ONEXEC; 733 op = OP_CHANGE_ONEXEC; 734 } else { 735 request = AA_MAY_CHANGE_PROFILE; 736 op = OP_CHANGE_PROFILE; 737 } 738 739 cred = get_current_cred(); --- 10 unchanged lines hidden (view full) --- 750 put_cred(cred); 751 return -EPERM; 752 } 753 754 target = aa_fqlookupn_profile(profile, fqname, strlen(fqname)); 755 if (!target) { 756 info = "profile not found"; 757 error = -ENOENT; | 731 request = AA_MAY_ONEXEC; 732 op = OP_CHANGE_ONEXEC; 733 } else { 734 request = AA_MAY_CHANGE_PROFILE; 735 op = OP_CHANGE_PROFILE; 736 } 737 738 cred = get_current_cred(); --- 10 unchanged lines hidden (view full) --- 749 put_cred(cred); 750 return -EPERM; 751 } 752 753 target = aa_fqlookupn_profile(profile, fqname, strlen(fqname)); 754 if (!target) { 755 info = "profile not found"; 756 error = -ENOENT; |
758 if (permtest || !COMPLAIN_MODE(profile)) | 757 if ((flags & AA_CHANGE_TEST) || 758 !COMPLAIN_MODE(profile)) |
759 goto audit; 760 /* released below */ 761 target = aa_new_null_profile(profile, false, fqname, 762 GFP_KERNEL); 763 if (!target) { 764 info = "failed null profile create"; 765 error = -ENOMEM; 766 goto audit; --- 9 unchanged lines hidden (view full) --- 776 777 /* check if tracing task is allowed to trace target domain */ 778 error = may_change_ptraced_domain(target); 779 if (error) { 780 info = "ptrace prevents transition"; 781 goto audit; 782 } 783 | 759 goto audit; 760 /* released below */ 761 target = aa_new_null_profile(profile, false, fqname, 762 GFP_KERNEL); 763 if (!target) { 764 info = "failed null profile create"; 765 error = -ENOMEM; 766 goto audit; --- 9 unchanged lines hidden (view full) --- 776 777 /* check if tracing task is allowed to trace target domain */ 778 error = may_change_ptraced_domain(target); 779 if (error) { 780 info = "ptrace prevents transition"; 781 goto audit; 782 } 783 |
784 if (permtest) | 784 if (flags & AA_CHANGE_TEST) |
785 goto audit; 786 | 785 goto audit; 786 |
787 if (onexec) | 787 if (flags & AA_CHANGE_ONEXEC) |
788 error = aa_set_current_onexec(target); 789 else 790 error = aa_replace_current_profile(target); 791 792audit: | 788 error = aa_set_current_onexec(target); 789 else 790 error = aa_replace_current_profile(target); 791 792audit: |
793 if (!permtest) | 793 if (!(flags & AA_CHANGE_TEST)) |
794 error = aa_audit_file(profile, &perms, op, request, NULL, 795 fqname, GLOBAL_ROOT_UID, info, error); 796 797 aa_put_profile(target); 798 aa_put_profile(profile); 799 put_cred(cred); 800 801 return error; 802} | 794 error = aa_audit_file(profile, &perms, op, request, NULL, 795 fqname, GLOBAL_ROOT_UID, info, error); 796 797 aa_put_profile(target); 798 aa_put_profile(profile); 799 put_cred(cred); 800 801 return error; 802} |