Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[firefly-linux-kernel-4.4.55.git] / security / apparmor / policy.c
index 813200384d97cfc7f06a76e9b2f6286be7dfa7ab..0f345c4dee5f46d7a6bb015d19105a0654a2f7d1 100644 (file)
@@ -87,7 +87,6 @@
 #include "include/policy.h"
 #include "include/policy_unpack.h"
 #include "include/resource.h"
-#include "include/sid.h"
 
 
 /* root profile namespace */
@@ -292,7 +291,6 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
        if (!ns->unconfined)
                goto fail_unconfined;
 
-       ns->unconfined->sid = aa_alloc_sid();
        ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |
            PFLAG_IMMUTABLE;
 
@@ -303,6 +301,8 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
         */
        ns->unconfined->ns = aa_get_namespace(ns);
 
+       atomic_set(&ns->uniq_null, 0);
+
        return ns;
 
 fail_unconfined:
@@ -497,7 +497,6 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
        /* released when @new is freed */
        new->parent = aa_get_profile(old->parent);
        new->ns = aa_get_namespace(old->ns);
-       new->sid = old->sid;
        __list_add_profile(&policy->profiles, new);
        /* inherit children */
        list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) {
@@ -635,83 +634,6 @@ void __init aa_free_root_ns(void)
         aa_put_namespace(ns);
 }
 
-/**
- * aa_alloc_profile - allocate, initialize and return a new profile
- * @hname: name of the profile  (NOT NULL)
- *
- * Returns: refcount profile or NULL on failure
- */
-struct aa_profile *aa_alloc_profile(const char *hname)
-{
-       struct aa_profile *profile;
-
-       /* freed by free_profile - usually through aa_put_profile */
-       profile = kzalloc(sizeof(*profile), GFP_KERNEL);
-       if (!profile)
-               return NULL;
-
-       if (!policy_init(&profile->base, NULL, hname)) {
-               kzfree(profile);
-               return NULL;
-       }
-
-       /* refcount released by caller */
-       return profile;
-}
-
-/**
- * aa_new_null_profile - create a new null-X learning profile
- * @parent: profile that caused this profile to be created (NOT NULL)
- * @hat: true if the null- learning profile is a hat
- *
- * Create a null- complain mode profile used in learning mode.  The name of
- * the profile is unique and follows the format of parent//null-sid.
- *
- * null profiles are added to the profile list but the list does not
- * hold a count on them so that they are automatically released when
- * not in use.
- *
- * Returns: new refcounted profile else NULL on failure
- */
-struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
-{
-       struct aa_profile *profile = NULL;
-       char *name;
-       u32 sid = aa_alloc_sid();
-
-       /* freed below */
-       name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
-       if (!name)
-               goto fail;
-       sprintf(name, "%s//null-%x", parent->base.hname, sid);
-
-       profile = aa_alloc_profile(name);
-       kfree(name);
-       if (!profile)
-               goto fail;
-
-       profile->sid = sid;
-       profile->mode = APPARMOR_COMPLAIN;
-       profile->flags = PFLAG_NULL;
-       if (hat)
-               profile->flags |= PFLAG_HAT;
-
-       /* released on free_profile */
-       profile->parent = aa_get_profile(parent);
-       profile->ns = aa_get_namespace(parent->ns);
-
-       write_lock(&profile->ns->lock);
-       __list_add_profile(&parent->base.profiles, profile);
-       write_unlock(&profile->ns->lock);
-
-       /* refcount released by caller */
-       return profile;
-
-fail:
-       aa_free_sid(sid);
-       return NULL;
-}
-
 /**
  * free_profile - free a profile
  * @profile: the profile to free  (MAYBE NULL)
@@ -749,7 +671,6 @@ static void free_profile(struct aa_profile *profile)
        aa_free_cap_rules(&profile->caps);
        aa_free_rlimit_rules(&profile->rlimits);
 
-       aa_free_sid(profile->sid);
        aa_put_dfa(profile->xmatch);
        aa_put_dfa(profile->policy.dfa);
 
@@ -790,6 +711,81 @@ void aa_free_profile_kref(struct kref *kref)
        free_profile(p);
 }
 
+/**
+ * aa_alloc_profile - allocate, initialize and return a new profile
+ * @hname: name of the profile  (NOT NULL)
+ *
+ * Returns: refcount profile or NULL on failure
+ */
+struct aa_profile *aa_alloc_profile(const char *hname)
+{
+       struct aa_profile *profile;
+
+       /* freed by free_profile - usually through aa_put_profile */
+       profile = kzalloc(sizeof(*profile), GFP_KERNEL);
+       if (!profile)
+               return NULL;
+
+       if (!policy_init(&profile->base, NULL, hname)) {
+               kzfree(profile);
+               return NULL;
+       }
+
+       /* refcount released by caller */
+       return profile;
+}
+
+/**
+ * aa_new_null_profile - create a new null-X learning profile
+ * @parent: profile that caused this profile to be created (NOT NULL)
+ * @hat: true if the null- learning profile is a hat
+ *
+ * Create a null- complain mode profile used in learning mode.  The name of
+ * the profile is unique and follows the format of parent//null-<uniq>.
+ *
+ * null profiles are added to the profile list but the list does not
+ * hold a count on them so that they are automatically released when
+ * not in use.
+ *
+ * Returns: new refcounted profile else NULL on failure
+ */
+struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
+{
+       struct aa_profile *profile = NULL;
+       char *name;
+       int uniq = atomic_inc_return(&parent->ns->uniq_null);
+
+       /* freed below */
+       name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
+       if (!name)
+               goto fail;
+       sprintf(name, "%s//null-%x", parent->base.hname, uniq);
+
+       profile = aa_alloc_profile(name);
+       kfree(name);
+       if (!profile)
+               goto fail;
+
+       profile->mode = APPARMOR_COMPLAIN;
+       profile->flags = PFLAG_NULL;
+       if (hat)
+               profile->flags |= PFLAG_HAT;
+
+       /* released on free_profile */
+       profile->parent = aa_get_profile(parent);
+       profile->ns = aa_get_namespace(parent->ns);
+
+       write_lock(&profile->ns->lock);
+       __list_add_profile(&parent->base.profiles, profile);
+       write_unlock(&profile->ns->lock);
+
+       /* refcount released by caller */
+       return profile;
+
+fail:
+       return NULL;
+}
+
 /* TODO: profile accounting - setup in remove */
 
 /**
@@ -972,7 +968,6 @@ static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,
                profile->parent = aa_get_profile((struct aa_profile *) policy);
        __list_add_profile(&policy->profiles, profile);
        /* released on free_profile */
-       profile->sid = aa_alloc_sid();
        profile->ns = aa_get_namespace(ns);
 }
 
@@ -1110,14 +1105,8 @@ audit:
        if (!error) {
                if (rename_profile)
                        __replace_profile(rename_profile, new_profile);
-               if (old_profile) {
-                       /* when there are both rename and old profiles
-                        * inherit old profiles sid
-                        */
-                       if (rename_profile)
-                               aa_free_sid(new_profile->sid);
+               if (old_profile)
                        __replace_profile(old_profile, new_profile);
-               }
                if (!(old_profile || rename_profile))
                        __add_new_profile(ns, policy, new_profile);
        }
@@ -1167,14 +1156,12 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
        if (fqname[0] == ':') {
                char *ns_name;
                name = aa_split_fqname(fqname, &ns_name);
-               if (ns_name) {
-                       /* released below */
-                       ns = aa_find_namespace(root, ns_name);
-                       if (!ns) {
-                               info = "namespace does not exist";
-                               error = -ENOENT;
-                               goto fail;
-                       }
+               /* released below */
+               ns = aa_find_namespace(root, ns_name);
+               if (!ns) {
+                       info = "namespace does not exist";
+                       error = -ENOENT;
+                       goto fail;
                }
        } else
                /* released below */