Skip to content

Commit

Permalink
sysctl: add sysctl to disallow unprivileged CLONE_NEWUSER by default
Browse files Browse the repository at this point in the history
add sysctl to disallow unprivileged CLONE_NEWUSER by default

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.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
[bwh: Remove unneeded binary sysctl bits]
[bwh: Keep this sysctl, but change the default to enabled]
Signed-off-by: Alexandre Frade <kernel@xanmod.org>
  • Loading branch information
hallyn authored and xanmod committed Jan 8, 2024
1 parent 6f58842 commit c236ba4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
15 changes: 15 additions & 0 deletions kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@

#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
Expand Down Expand Up @@ -2265,6 +2270,10 @@ __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 @@ -3411,6 +3420,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
13 changes: 13 additions & 0 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ static enum sysctl_writes_mode sysctl_writes_strict = SYSCTL_WRITES_STRICT;
int sysctl_legacy_va_layout;
#endif

#ifdef CONFIG_USER_NS
extern int unprivileged_userns_clone;
#endif

#endif /* CONFIG_SYSCTL */

/*
Expand Down Expand Up @@ -1633,6 +1637,15 @@ static struct ctl_table kern_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_TWO,
},
#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
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include <linux/bsearch.h>
#include <linux/sort.h>

/* sysctl */
int unprivileged_userns_clone = 1;

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

Expand Down

0 comments on commit c236ba4

Please sign in to comment.