summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-01-16 00:42:21 -0800
committerJohn Johansen <john.johansen@canonical.com>2017-01-16 01:18:19 -0800
commit1741e9eb8c15de0ba6598a342c51d0688cb569d2 (patch)
tree602e0a3766d738f391ead43c93793af732a3e03b
parent8399588a7f9def9195e577f988ad06f2a0ffb1af (diff)
downloadlinux-1741e9eb8c15de0ba6598a342c51d0688cb569d2.tar.gz
apparmor: add strn version of lookup_profile fn
Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r--security/apparmor/include/policy.h2
-rw-r--r--security/apparmor/policy.c36
2 files changed, 27 insertions, 11 deletions
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index f55ecb8b3777..c90f4a2ffe57 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -177,6 +177,8 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
 void aa_free_profile(struct aa_profile *profile);
 void aa_free_profile_kref(struct kref *kref);
 struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
+struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
+				      size_t n);
 struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
 struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
 
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index a4bf6756bc1c..291810490eaf 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -427,9 +427,10 @@ static struct aa_policy *__lookup_parent(struct aa_ns *ns,
 }
 
 /**
- * __lookup_profile - lookup the profile matching @hname
+ * __lookupn_profile - lookup the profile matching @hname
  * @base: base list to start looking up profile name from  (NOT NULL)
  * @hname: hierarchical profile name  (NOT NULL)
+ * @n: length of @hname
  *
  * Requires: rcu_read_lock be held
  *
@@ -437,53 +438,66 @@ static struct aa_policy *__lookup_parent(struct aa_ns *ns,
  *
  * Do a relative name lookup, recursing through profile tree.
  */
-static struct aa_profile *__lookup_profile(struct aa_policy *base,
-					   const char *hname)
+static struct aa_profile *__lookupn_profile(struct aa_policy *base,
+					    const char *hname, size_t n)
 {
 	struct aa_profile *profile = NULL;
-	char *split;
+	const char *split;
 
-	for (split = strstr(hname, "//"); split;) {
+	for (split = strnstr(hname, "//", n); split;
+	     split = strnstr(hname, "//", n)) {
 		profile = __strn_find_child(&base->profiles, hname,
 					    split - hname);
 		if (!profile)
 			return NULL;
 
 		base = &profile->base;
+		n -= split + 2 - hname;
 		hname = split + 2;
-		split = strstr(hname, "//");
 	}
 
-	profile = __find_child(&base->profiles, hname);
+	if (n)
+		return __strn_find_child(&base->profiles, hname, n);
+	return NULL;
+}
 
-	return profile;
+static struct aa_profile *__lookup_profile(struct aa_policy *base,
+					   const char *hname)
+{
+	return __lookupn_profile(base, hname, strlen(hname));
 }
 
 /**
  * aa_lookup_profile - find a profile by its full or partial name
  * @ns: the namespace to start from (NOT NULL)
  * @hname: name to do lookup on.  Does not contain namespace prefix (NOT NULL)
+ * @n: size of @hname
  *
  * Returns: refcounted profile or NULL if not found
  */
-struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *hname)
+struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
+				      size_t n)
 {
 	struct aa_profile *profile;
 
 	rcu_read_lock();
 	do {
-		profile = __lookup_profile(&ns->base, hname);
+		profile = __lookupn_profile(&ns->base, hname, n);
 	} while (profile && !aa_get_profile_not0(profile));
 	rcu_read_unlock();
 
 	/* the unconfined profile is not in the regular profile list */
-	if (!profile && strcmp(hname, "unconfined") == 0)
+	if (!profile && strncmp(hname, "unconfined", n) == 0)
 		profile = aa_get_newest_profile(ns->unconfined);
 
 	/* refcount released by caller */
 	return profile;
 }
 
+struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *hname)
+{
+	return aa_lookupn_profile(ns, hname, strlen(hname));
+}
 /**
  * replacement_allowed - test to see if replacement is allowed
  * @profile: profile to test if it can be replaced  (MAYBE NULL)