diff options
Diffstat (limited to 'security/apparmor/domain.c')
-rw-r--r-- | security/apparmor/domain.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 01b7bd669a88..454bcd7f3452 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
@@ -144,7 +144,7 @@ static struct aa_profile *__attach_match(const char *name, | |||
144 | int len = 0; | 144 | int len = 0; |
145 | struct aa_profile *profile, *candidate = NULL; | 145 | struct aa_profile *profile, *candidate = NULL; |
146 | 146 | ||
147 | list_for_each_entry(profile, head, base.list) { | 147 | list_for_each_entry_rcu(profile, head, base.list) { |
148 | if (profile->flags & PFLAG_NULL) | 148 | if (profile->flags & PFLAG_NULL) |
149 | continue; | 149 | continue; |
150 | if (profile->xmatch && profile->xmatch_len > len) { | 150 | if (profile->xmatch && profile->xmatch_len > len) { |
@@ -177,9 +177,9 @@ static struct aa_profile *find_attach(struct aa_namespace *ns, | |||
177 | { | 177 | { |
178 | struct aa_profile *profile; | 178 | struct aa_profile *profile; |
179 | 179 | ||
180 | read_lock(&ns->lock); | 180 | rcu_read_lock(); |
181 | profile = aa_get_profile(__attach_match(name, list)); | 181 | profile = aa_get_profile(__attach_match(name, list)); |
182 | read_unlock(&ns->lock); | 182 | rcu_read_unlock(); |
183 | 183 | ||
184 | return profile; | 184 | return profile; |
185 | } | 185 | } |
@@ -641,7 +641,10 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
641 | if (count) { | 641 | if (count) { |
642 | /* attempting to change into a new hat or switch to a sibling */ | 642 | /* attempting to change into a new hat or switch to a sibling */ |
643 | struct aa_profile *root; | 643 | struct aa_profile *root; |
644 | root = PROFILE_IS_HAT(profile) ? profile->parent : profile; | 644 | if (PROFILE_IS_HAT(profile)) |
645 | root = aa_get_profile_rcu(&profile->parent); | ||
646 | else | ||
647 | root = aa_get_profile(profile); | ||
645 | 648 | ||
646 | /* find first matching hat */ | 649 | /* find first matching hat */ |
647 | for (i = 0; i < count && !hat; i++) | 650 | for (i = 0; i < count && !hat; i++) |
@@ -653,6 +656,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
653 | error = -ECHILD; | 656 | error = -ECHILD; |
654 | else | 657 | else |
655 | error = -ENOENT; | 658 | error = -ENOENT; |
659 | aa_put_profile(root); | ||
656 | goto out; | 660 | goto out; |
657 | } | 661 | } |
658 | 662 | ||
@@ -667,6 +671,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
667 | 671 | ||
668 | /* freed below */ | 672 | /* freed below */ |
669 | name = new_compound_name(root->base.hname, hats[0]); | 673 | name = new_compound_name(root->base.hname, hats[0]); |
674 | aa_put_profile(root); | ||
670 | target = name; | 675 | target = name; |
671 | /* released below */ | 676 | /* released below */ |
672 | hat = aa_new_null_profile(profile, 1); | 677 | hat = aa_new_null_profile(profile, 1); |
@@ -676,6 +681,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
676 | goto audit; | 681 | goto audit; |
677 | } | 682 | } |
678 | } else { | 683 | } else { |
684 | aa_put_profile(root); | ||
679 | target = hat->base.hname; | 685 | target = hat->base.hname; |
680 | if (!PROFILE_IS_HAT(hat)) { | 686 | if (!PROFILE_IS_HAT(hat)) { |
681 | info = "target not hat"; | 687 | info = "target not hat"; |