]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
UBUNTU: SAUCE: add a sysctl to disable unprivileged user namespace unsharing
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 5 Jan 2016 20:12:21 +0000 (20:12 +0000)
committerTim Gardner <tim.gardner@canonical.com>
Mon, 29 Feb 2016 15:54:46 +0000 (08:54 -0700)
It is turned on by default, but can be turned off if admins prefer or,
more importantly, if a security vulnerability is found.

The intent is to use this as mitigation so long as Ubuntu is on the
cutting edge of enablement for things like unprivileged filesystem
mounting.

(This patch is tweaked from the one currently still in Debian sid, which
in turn came from the patch we had in saucy)

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
[bwh: Remove unneeded binary sysctl bits]
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
kernel/fork.c
kernel/sysctl.c
kernel/user_namespace.c

index c001ea4a2c6d66a05f2dac8132d7844e280e9df1..8a5aa584df2c71882ded365f1c19240ca007a6ec 100644 (file)
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/task.h>
+#ifdef CONFIG_USER_NS
+extern int unprivileged_userns_clone;
+#else
+#define unprivileged_userns_clone 0
+#endif
 
 /*
  * Minimum number of threads to boot the kernel
@@ -1258,6 +1263,10 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
                return ERR_PTR(-EINVAL);
 
+       if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
+               if (!capable(CAP_SYS_ADMIN))
+                       return ERR_PTR(-EPERM);
+
        /*
         * Thread groups must share signals as well, and detached threads
         * can only be started up within the thread group.
@@ -1984,6 +1993,12 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
        if (unshare_flags & CLONE_NEWNS)
                unshare_flags |= CLONE_FS;
 
+       if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
+               err = -EPERM;
+               if (!capable(CAP_SYS_ADMIN))
+                       goto bad_unshare_out;
+       }
+
        err = check_unshare_flags(unshare_flags);
        if (err)
                goto bad_unshare_out;
index dc6858d6639ed022d65129bdbb869ff7bcc05789..a34aa4048ad1ca999031dae9b3f02f5de516b4a7 100644 (file)
@@ -103,6 +103,9 @@ extern int core_uses_pid;
 extern char core_pattern[];
 extern unsigned int core_pipe_limit;
 #endif
+#ifdef CONFIG_USER_NS
+extern int unprivileged_userns_clone;
+#endif
 extern int pid_max;
 extern int pid_max_min, pid_max_max;
 extern int percpu_pagelist_fraction;
@@ -482,6 +485,15 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = proc_dointvec,
        },
 #endif
+#ifdef CONFIG_USER_NS
+       {
+               .procname       = "unprivileged_userns_clone",
+               .data           = &unprivileged_userns_clone,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+#endif
 #ifdef CONFIG_PROC_SYSCTL
        {
                .procname       = "tainted",
index 88fefa68c5164c88e5ec2487c942b15e3914666b..2d1db6cac01176cfe2af39bdb3b1c01e6ec5168f 100644 (file)
 #include <linux/projid.h>
 #include <linux/fs_struct.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);