]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/user_namespace.c
cpu/SMT: State SMT is disabled even with nosmt and without "=force"
[mirror_ubuntu-bionic-kernel.git] / kernel / user_namespace.c
index 246d4d4ce5c70cde4b5c9ed7fd33f54c1efe5a3e..44294dc0a5f2c55f9a12085bbcabf668b70be45e 100644 (file)
 #include <linux/bsearch.h>
 #include <linux/sort.h>
 
+/*
+ * sysctl determining whether unprivileged users may unshare a new
+ * userns.  Allowed by default
+ */
+int unprivileged_userns_clone = 1;
+
 static struct kmem_cache *user_ns_cachep __read_mostly;
 static DEFINE_MUTEX(userns_state_mutex);
 
@@ -858,7 +864,16 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        unsigned idx;
        struct uid_gid_extent extent;
        char *kbuf = NULL, *pos, *next_line;
-       ssize_t ret = -EINVAL;
+       ssize_t ret;
+
+       /* Only allow < page size writes at the beginning of the file */
+       if ((*ppos != 0) || (count >= PAGE_SIZE))
+               return -EINVAL;
+
+       /* Slurp in the user data */
+       kbuf = memdup_user_nul(buf, count);
+       if (IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
 
        /*
         * The userns_state_mutex serializes all writes to any given map.
@@ -894,19 +909,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
                goto out;
 
-       /* Only allow < page size writes at the beginning of the file */
-       ret = -EINVAL;
-       if ((*ppos != 0) || (count >= PAGE_SIZE))
-               goto out;
-
-       /* Slurp in the user data */
-       kbuf = memdup_user_nul(buf, count);
-       if (IS_ERR(kbuf)) {
-               ret = PTR_ERR(kbuf);
-               kbuf = NULL;
-               goto out;
-       }
-
        /* Parse the user data */
        ret = -EINVAL;
        pos = kbuf;
@@ -977,10 +979,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
                goto out;
 
-       ret = sort_idmaps(&new_map);
-       if (ret < 0)
-               goto out;
-
        ret = -EPERM;
        /* Map the lower ids from the parent user namespace to the
         * kernel global id space.
@@ -1007,6 +1005,14 @@ static ssize_t map_write(struct file *file, const char __user *buf,
                e->lower_first = lower_first;
        }
 
+       /*
+        * If we want to use binary search for lookup, this clones the extent
+        * array and sorts both copies.
+        */
+       ret = sort_idmaps(&new_map);
+       if (ret < 0)
+               goto out;
+
        /* Install the map */
        if (new_map.nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS) {
                memcpy(map->extent, new_map.extent,
@@ -1235,6 +1241,7 @@ bool current_in_userns(const struct user_namespace *target_ns)
 {
        return in_userns(target_ns, current_user_ns());
 }
+EXPORT_SYMBOL(current_in_userns);
 
 static inline struct user_namespace *to_user_ns(struct ns_common *ns)
 {