Verified Commit a51b0f37 authored by Jan Alexander Steffens (heftig)'s avatar Jan Alexander Steffens (heftig) Committed by David Runge
Browse files

ZEN: Add sysctl and CONFIG to disallow unprivileged CLONE_NEWUSER

Our default behavior continues to match the vanilla kernel.
parent 8a084036
......@@ -137,6 +137,8 @@ static inline void set_rlimit_ucount_max(struct user_namespace *ns,
#ifdef CONFIG_USER_NS
extern int unprivileged_userns_clone;
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
if (ns)
......@@ -170,6 +172,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;
......
......@@ -1200,6 +1200,22 @@ config USER_NS
If unsure, say N.
config USER_NS_UNPRIVILEGED
bool "Allow unprivileged users to create namespaces"
default y
depends on USER_NS
help
When disabled, unprivileged users will not be able to create
new namespaces. Allowing users to create their own namespaces
has been part of several recent local privilege escalation
exploits, so if you need user namespaces but are
paranoid^Wsecurity-conscious you want to disable this.
This setting can be overridden at runtime via the
kernel.unprivileged_userns_clone sysctl.
If unsure, say Y.
config PID_NS
bool "PID Namespaces"
default y
......
......@@ -99,6 +99,10 @@
#include <linux/io_uring.h>
#include <linux/bpf.h>
#ifdef CONFIG_USER_NS
#include <linux/user_namespace.h>
#endif
#include <asm/pgalloc.h>
#include <linux/uaccess.h>
#include <asm/mmu_context.h>
......@@ -1899,6 +1903,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.
......@@ -3003,6 +3011,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;
......
......@@ -105,6 +105,9 @@
#ifdef CONFIG_LOCKUP_DETECTOR
#include <linux/nmi.h>
#endif
#ifdef CONFIG_USER_NS
#include <linux/user_namespace.h>
#endif
#if defined(CONFIG_SYSCTL)
......@@ -1908,6 +1911,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",
......
......@@ -21,6 +21,13 @@
#include <linux/bsearch.h>
#include <linux/sort.h>
/* sysctl */
#ifdef CONFIG_USER_NS_UNPRIVILEGED
int unprivileged_userns_clone = 1;
#else
int unprivileged_userns_clone;
#endif
static struct kmem_cache *user_ns_cachep __read_mostly;
static DEFINE_MUTEX(userns_state_mutex);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment