]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
apparmor: refactor aa_prepare_ns into prepare_ns and create_ns routines
authorJohn Johansen <john.johansen@canonical.com>
Thu, 22 Sep 2016 19:51:11 +0000 (12:51 -0700)
committerTim Gardner <tim.gardner@canonical.com>
Mon, 20 Feb 2017 03:57:58 +0000 (20:57 -0700)
BugLink: http://bugs.launchpad.net/bugs/1611078
Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
security/apparmor/include/policy_ns.h
security/apparmor/policy_ns.c

index 65b1e1ec749cb063a05ce988ea8a3a923e8aee3e..0325118b27939c6300ad79d60c30c21ffe12bfed 100644 (file)
@@ -88,6 +88,7 @@ void aa_free_ns_kref(struct kref *kref);
 
 struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
 struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
+struct aa_ns *aa_create_ns(struct aa_ns *parent, const char *name);
 struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name);
 void __aa_remove_ns(struct aa_ns *ns);
 
index 19adb24d00a08c7dbeff35cab71f5c7637274ad0..cbef81674012eaa05710912a174dd3ad5cbe7058 100644 (file)
@@ -199,43 +199,73 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
        return aa_findn_ns(root, name, strlen(name));
 }
 
+static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name)
+{
+       struct aa_ns *ns;
+
+       AA_BUG(!mutex_is_locked(&parent->lock));
+
+       ns = alloc_ns(parent->base.hname, name);
+       if (!ns)
+               return NULL;
+       mutex_lock(&ns->lock);
+       if (__aa_fs_ns_mkdir(ns, ns_subns_dir(parent), name)) {
+               AA_ERROR("Failed to create interface for ns %s\n",
+                        ns->base.name);
+               mutex_unlock(&ns->lock);
+               aa_free_ns(ns);
+               return ERR_PTR(-ENOMEM);
+       } else {
+               ns->parent = aa_get_ns(parent);
+               ns->level = parent->level + 1;
+               list_add_rcu(&ns->base.list, &parent->sub_ns);
+               /* add list ref */
+               aa_get_ns(ns);
+       }
+       mutex_unlock(&ns->lock);
+
+       return ns;
+}
+
+struct aa_ns *aa_create_ns(struct aa_ns *parent, const char *name)
+{
+       struct aa_ns *ns;
+
+       mutex_lock(&parent->lock);
+       /* try and find the specified ns */
+       /* released by caller */
+       ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
+       if (!ns)
+{
+printk("apparmor creating ns %s\n", name);
+               ns = __aa_create_ns(parent, name);
+}
+       else
+               ns = ERR_PTR(-EEXIST);
+       mutex_unlock(&parent->lock);
+printk("apparmor unlocking parent ns\n");
+       /* return ref */
+       return ns;
+}
+
 /**
  * aa_prepare_ns - find an existing or create a new namespace of @name
- * @root: ns to treat as root
+ * @parent: ns to treat as parent
  * @name: the namespace to find or add  (NOT NULL)
  *
- * Returns: refcounted namespace or NULL if failed to create one
+ * Returns: refcounted namespace or PTR_ERR if failed to create one
  */
-struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name)
+struct aa_ns *aa_prepare_ns(struct aa_ns *parent, const char *name)
 {
        struct aa_ns *ns;
 
-       mutex_lock(&root->lock);
+       mutex_lock(&parent->lock);
        /* try and find the specified ns and if it doesn't exist create it */
        /* released by caller */
-       ns = aa_get_ns(__aa_findn_ns(&root->sub_ns, name, strlen(name)));
-       if (!ns) {
-               ns = alloc_ns(root->base.hname, name);
-               if (!ns)
-                       goto out;
-               mutex_lock(&ns->lock);
-               if (__aa_fs_ns_mkdir(ns, ns_subns_dir(root), name)) {
-                       AA_ERROR("Failed to create interface for ns %s\n",
-                                ns->base.name);
-                       mutex_unlock(&ns->lock);
-                       aa_free_ns(ns);
-                       ns = NULL;
-                       goto out;
-               }
-               ns->parent = aa_get_ns(root);
-               ns->level = root->level + 1;
-               list_add_rcu(&ns->base.list, &root->sub_ns);
-               /* add list ref */
-               aa_get_ns(ns);
-               mutex_unlock(&ns->lock);
-       }
-out:
-       mutex_unlock(&root->lock);
+       ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
+       if (!ns)
+               ns = __aa_create_ns(parent, name);
+       mutex_unlock(&parent->lock);
 
        /* return ref */
        return ns;