Skip to content

Commit

Permalink
add sysctl to disallow unprivileged CLONE_NEWUSER by default
Browse files Browse the repository at this point in the history
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
[bwh: Remove unneeded binary sysctl bits]
Signed-off-by: Daniel Micay <danielmicay@gmail.com>
[thibaut.sautereau@ssi.gouv.fr: Adapt to sysctl code refactoring]
Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
Signed-off-by: Levente Polyak <levente@leventepolyak.net>
  • Loading branch information
hallyn authored and anthraxx committed Oct 13, 2020
1 parent 445db3d commit ab5eea9
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/linux/user_namespace.h
Expand Up @@ -106,6 +106,8 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type);

#ifdef CONFIG_USER_NS

extern int unprivileged_userns_clone;

static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
if (ns)
Expand Down Expand Up @@ -139,6 +141,8 @@ extern bool current_in_userns(const struct user_namespace *target_ns);
struct ns_common *ns_get_owner(struct ns_common *ns);
#else

#define unprivileged_userns_clone 0

static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
return &init_user_ns;
Expand Down
11 changes: 11 additions & 0 deletions kernel/fork.c
Expand Up @@ -82,6 +82,7 @@
#include <linux/perf_event.h>
#include <linux/posix-timers.h>
#include <linux/user-return-notifier.h>
#include <linux/user_namespace.h>
#include <linux/oom.h>
#include <linux/khugepaged.h>
#include <linux/signalfd.h>
Expand Down Expand Up @@ -1843,6 +1844,10 @@ static __latent_entropy struct task_struct *copy_process(
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.
Expand Down Expand Up @@ -2906,6 +2911,12 @@ int ksys_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;
Expand Down
12 changes: 12 additions & 0 deletions kernel/sysctl.c
Expand Up @@ -103,6 +103,9 @@
#ifdef CONFIG_LOCKUP_DETECTOR
#include <linux/nmi.h>
#endif
#ifdef CONFIG_USER_NS
#include <linux/user_namespace.h>
#endif

#if defined(CONFIG_SYSCTL)

Expand Down Expand Up @@ -1902,6 +1905,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",
Expand Down
3 changes: 3 additions & 0 deletions kernel/user_namespace.c
Expand Up @@ -21,6 +21,9 @@
#include <linux/bsearch.h>
#include <linux/sort.h>

/* sysctl */
int unprivileged_userns_clone;

static struct kmem_cache *user_ns_cachep __read_mostly;
static DEFINE_MUTEX(userns_state_mutex);

Expand Down

0 comments on commit ab5eea9

Please sign in to comment.