From 6bd227c9e1cf1401db656f1644498f573a6ad058 Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Fri, 31 May 2013 19:12:12 +0100 Subject: [PATCH] add sysctl to allow disabling unprivileged CLONE_NEWUSER This is a short-term patch. Unprivileged use of CLONE_NEWUSER is certainly an intended feature of user namespaces. However for at least saucy we want to make sure that, if any security issues are found, we have a fail-safe. [bwh: Remove unneeded binary sysctl bits] [bwh: Keep this sysctl, but change the default to enabled] [heftig: correct commit subject to reduce confusion] [heftig: for 6.17, move all code into kernel/fork.c] --- kernel/fork.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/kernel/fork.c b/kernel/fork.c index 3da0f08615a95e..07349223afff68 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -123,6 +123,12 @@ #include +#ifdef CONFIG_USER_NS +static int unprivileged_userns_clone = 1; +#else +#define unprivileged_userns_clone 1 +#endif + /* * Minimum number of threads to boot the kernel */ @@ -1990,6 +1996,11 @@ __latent_entropy struct task_struct *copy_process( return ERR_PTR(-EINVAL); } + if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) { + if (!capable(CAP_SYS_ADMIN)) + return ERR_PTR(-EPERM); + } + /* * Force any signals received before this point to be delivered * before the fork happens. Collect up signals sent to multiple @@ -3025,6 +3036,10 @@ static int check_unshare_flags(unsigned long unshare_flags) if (!current_is_single_threaded()) return -EINVAL; } + if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + } return 0; } @@ -3255,6 +3270,15 @@ static const struct ctl_table fork_sysctl_table[] = { .mode = 0644, .proc_handler = sysctl_max_threads, }, +#ifdef CONFIG_USER_NS + { + .procname = "unprivileged_userns_clone", + .data = &unprivileged_userns_clone, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif }; static int __init init_fork_sysctl(void)