diff options
author | John Johansen <john.johansen@canonical.com> | 2017-08-16 15:40:49 +0300 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2017-09-22 23:00:58 +0300 |
commit | 290638a52a808d658bd04b746b3ca46886c157e0 (patch) | |
tree | 0168c39c9e3265e7a053dbcbea09dc2d4864f16b | |
parent | d07881d2edb0ab783846730629ac2faeaafdf4f1 (diff) | |
download | linux-290638a52a808d658bd04b746b3ca46886c157e0.tar.xz |
apparmor: fix race condition in null profile creation
There is a race when null- profile is being created between the
initial lookup/creation of the profile and lock/addition of the
profile. This could result in multiple version of a profile being
added to the list which need to be removed/replaced.
Since these are learning profile their is no affect on mediation.
Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r-- | security/apparmor/policy.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index a81a384a63b1..4243b0c3f0e4 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -500,7 +500,8 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base, struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, const char *base, gfp_t gfp) { - struct aa_profile *profile; + struct aa_profile *p, *profile; + const char *bname; char *name; AA_BUG(!parent); @@ -523,7 +524,8 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, name: /* lookup to see if this is a dup creation */ - profile = aa_find_child(parent, basename(name)); + bname = basename(name); + profile = aa_find_child(parent, bname); if (profile) goto out; @@ -544,7 +546,13 @@ name: profile->policy.dfa = aa_get_dfa(nulldfa); mutex_lock(&profile->ns->lock); - __add_profile(&parent->base.profiles, profile); + p = __find_child(&parent->base.profiles, bname); + if (p) { + aa_free_profile(profile); + profile = aa_get_profile(p); + } else { + __add_profile(&parent->base.profiles, profile); + } mutex_unlock(&profile->ns->lock); /* refcount released by caller */ |