Skip to content

Commit 1625f44

Browse files
committed
ZEN: Add sysctl and CONFIG to disallow unprivileged CLONE_NEWUSER
Our default behavior continues to match the vanilla kernel.
1 parent ffd294d commit 1625f44

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

include/linux/user_namespace.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ static inline void set_userns_rlimit_max(struct user_namespace *ns,
159159

160160
#ifdef CONFIG_USER_NS
161161

162+
extern int unprivileged_userns_clone;
163+
162164
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
163165
{
164166
if (ns)
@@ -192,6 +194,8 @@ extern bool current_in_userns(const struct user_namespace *target_ns);
192194
struct ns_common *ns_get_owner(struct ns_common *ns);
193195
#else
194196

197+
#define unprivileged_userns_clone 0
198+
195199
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
196200
{
197201
return &init_user_ns;

init/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,22 @@ config USER_NS
13101310

13111311
If unsure, say N.
13121312

1313+
config USER_NS_UNPRIVILEGED
1314+
bool "Allow unprivileged users to create namespaces"
1315+
default y
1316+
depends on USER_NS
1317+
help
1318+
When disabled, unprivileged users will not be able to create
1319+
new namespaces. Allowing users to create their own namespaces
1320+
has been part of several recent local privilege escalation
1321+
exploits, so if you need user namespaces but are
1322+
paranoid^Wsecurity-conscious you want to disable this.
1323+
1324+
This setting can be overridden at runtime via the
1325+
kernel.unprivileged_userns_clone sysctl.
1326+
1327+
If unsure, say Y.
1328+
13131329
config PID_NS
13141330
bool "PID Namespaces"
13151331
default y

kernel/fork.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@
106106
#include <linux/pidfs.h>
107107
#include <linux/tick.h>
108108

109+
#ifdef CONFIG_USER_NS
110+
#include <linux/user_namespace.h>
111+
#endif
112+
109113
#include <asm/pgalloc.h>
110114
#include <linux/uaccess.h>
111115
#include <asm/mmu_context.h>
@@ -2158,6 +2162,10 @@ __latent_entropy struct task_struct *copy_process(
21582162
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
21592163
return ERR_PTR(-EINVAL);
21602164

2165+
if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
2166+
if (!capable(CAP_SYS_ADMIN))
2167+
return ERR_PTR(-EPERM);
2168+
21612169
/*
21622170
* Thread groups must share signals as well, and detached threads
21632171
* can only be started up within the thread group.
@@ -3311,6 +3319,12 @@ int ksys_unshare(unsigned long unshare_flags)
33113319
if (unshare_flags & CLONE_NEWNS)
33123320
unshare_flags |= CLONE_FS;
33133321

3322+
if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
3323+
err = -EPERM;
3324+
if (!capable(CAP_SYS_ADMIN))
3325+
goto bad_unshare_out;
3326+
}
3327+
33143328
err = check_unshare_flags(unshare_flags);
33153329
if (err)
33163330
goto bad_unshare_out;

kernel/sysctl.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@
8080
#ifdef CONFIG_RT_MUTEXES
8181
#include <linux/rtmutex.h>
8282
#endif
83+
#ifdef CONFIG_USER_NS
84+
#include <linux/user_namespace.h>
85+
#endif
8386

8487
/* shared constants to be used in various sysctls */
8588
const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 };
@@ -1617,6 +1620,15 @@ static struct ctl_table kern_table[] = {
16171620
.mode = 0644,
16181621
.proc_handler = proc_dointvec,
16191622
},
1623+
#ifdef CONFIG_USER_NS
1624+
{
1625+
.procname = "unprivileged_userns_clone",
1626+
.data = &unprivileged_userns_clone,
1627+
.maxlen = sizeof(int),
1628+
.mode = 0644,
1629+
.proc_handler = proc_dointvec,
1630+
},
1631+
#endif
16201632
#ifdef CONFIG_PROC_SYSCTL
16211633
{
16221634
.procname = "tainted",

kernel/user_namespace.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222
#include <linux/bsearch.h>
2323
#include <linux/sort.h>
2424

25+
/* sysctl */
26+
#ifdef CONFIG_USER_NS_UNPRIVILEGED
27+
int unprivileged_userns_clone = 1;
28+
#else
29+
int unprivileged_userns_clone;
30+
#endif
31+
2532
static struct kmem_cache *user_ns_cachep __ro_after_init;
2633
static DEFINE_MUTEX(userns_state_mutex);
2734

0 commit comments

Comments
 (0)