diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-11-13 01:48:07 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-11-13 01:48:07 -0500 |
commit | 6214b54cbf0778804de1297444c7661e70bc4d74 (patch) | |
tree | 262a96d1be839a30e6e8d3f3452806b7f337148c /security/apparmor/policy.c | |
parent | 05193639ca977cc889668718adb38db6d585045b (diff) | |
parent | ba027da8eb309252cb611f23808da51487f68e12 (diff) |
Merge tag 'asoc-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v3.7
A few small fixes plus a large but simple change for WM5102 which writes
out a bunch of register updates to the device when we enable the clock
as recommended following chip evaluation.
Diffstat (limited to 'security/apparmor/policy.c')
-rw-r--r-- | security/apparmor/policy.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index cf5fd220309b..813200384d97 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
@@ -724,6 +724,8 @@ fail: | |||
724 | */ | 724 | */ |
725 | static void free_profile(struct aa_profile *profile) | 725 | static void free_profile(struct aa_profile *profile) |
726 | { | 726 | { |
727 | struct aa_profile *p; | ||
728 | |||
727 | AA_DEBUG("%s(%p)\n", __func__, profile); | 729 | AA_DEBUG("%s(%p)\n", __func__, profile); |
728 | 730 | ||
729 | if (!profile) | 731 | if (!profile) |
@@ -751,7 +753,27 @@ static void free_profile(struct aa_profile *profile) | |||
751 | aa_put_dfa(profile->xmatch); | 753 | aa_put_dfa(profile->xmatch); |
752 | aa_put_dfa(profile->policy.dfa); | 754 | aa_put_dfa(profile->policy.dfa); |
753 | 755 | ||
754 | aa_put_profile(profile->replacedby); | 756 | /* put the profile reference for replacedby, but not via |
757 | * put_profile(kref_put). | ||
758 | * replacedby can form a long chain that can result in cascading | ||
759 | * frees that blows the stack because kref_put makes a nested fn | ||
760 | * call (it looks like recursion, with free_profile calling | ||
761 | * free_profile) for each profile in the chain lp#1056078. | ||
762 | */ | ||
763 | for (p = profile->replacedby; p; ) { | ||
764 | if (atomic_dec_and_test(&p->base.count.refcount)) { | ||
765 | /* no more refs on p, grab its replacedby */ | ||
766 | struct aa_profile *next = p->replacedby; | ||
767 | /* break the chain */ | ||
768 | p->replacedby = NULL; | ||
769 | /* now free p, chain is broken */ | ||
770 | free_profile(p); | ||
771 | |||
772 | /* follow up with next profile in the chain */ | ||
773 | p = next; | ||
774 | } else | ||
775 | break; | ||
776 | } | ||
755 | 777 | ||
756 | kzfree(profile); | 778 | kzfree(profile); |
757 | } | 779 | } |