Blob Blame History Raw
From 29ec50aa3815bddeee97a224e917a310b677ca15 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 16 Aug 2017 05:40:49 -0700
Subject: [PATCH 13/17] apparmor: fix race condition in null profile creation
References: FATE#323500
Patch-mainline: v4.14-rc2
Git-commit: 290638a52a808d658bd04b746b3ca46886c157e0

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>
Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
---
 security/apparmor/policy.c | 14 +++++++++++---
 1 file 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 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
 	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 */
-- 
2.14.1