Skip to content

Commit 35d79b5

Browse files
committed
ZEN: Add sysctl and CONFIG to disallow unprivileged CLONE_NEWUSER
Our default behavior continues to match the vanilla kernel.
1 parent 0dd3ee3 commit 35d79b5

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
@@ -156,6 +156,8 @@ static inline void set_userns_rlimit_max(struct user_namespace *ns,
156156

157157
#ifdef CONFIG_USER_NS
158158

159+
extern int unprivileged_userns_clone;
160+
159161
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
160162
{
161163
if (ns)
@@ -189,6 +191,8 @@ extern bool current_in_userns(const struct user_namespace *target_ns);
189191
struct ns_common *ns_get_owner(struct ns_common *ns);
190192
#else
191193

194+
#define unprivileged_userns_clone 0
195+
192196
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
193197
{
194198
return &init_user_ns;

init/Kconfig

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

12271227
If unsure, say N.
12281228

1229+
config USER_NS_UNPRIVILEGED
1230+
bool "Allow unprivileged users to create namespaces"
1231+
default y
1232+
depends on USER_NS
1233+
help
1234+
When disabled, unprivileged users will not be able to create
1235+
new namespaces. Allowing users to create their own namespaces
1236+
has been part of several recent local privilege escalation
1237+
exploits, so if you need user namespaces but are
1238+
paranoid^Wsecurity-conscious you want to disable this.
1239+
1240+
This setting can be overridden at runtime via the
1241+
kernel.unprivileged_userns_clone sysctl.
1242+
1243+
If unsure, say Y.
1244+
12291245
config PID_NS
12301246
bool "PID Namespaces"
12311247
default y

kernel/fork.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100
#include <linux/user_events.h>
101101
#include <linux/iommu.h>
102102

103+
#ifdef CONFIG_USER_NS
104+
#include <linux/user_namespace.h>
105+
#endif
106+
103107
#include <asm/pgalloc.h>
104108
#include <linux/uaccess.h>
105109
#include <asm/mmu_context.h>
@@ -2265,6 +2269,10 @@ __latent_entropy struct task_struct *copy_process(
22652269
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
22662270
return ERR_PTR(-EINVAL);
22672271

2272+
if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
2273+
if (!capable(CAP_SYS_ADMIN))
2274+
return ERR_PTR(-EPERM);
2275+
22682276
/*
22692277
* Thread groups must share signals as well, and detached threads
22702278
* can only be started up within the thread group.
@@ -3411,6 +3419,12 @@ int ksys_unshare(unsigned long unshare_flags)
34113419
if (unshare_flags & CLONE_NEWNS)
34123420
unshare_flags |= CLONE_FS;
34133421

3422+
if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
3423+
err = -EPERM;
3424+
if (!capable(CAP_SYS_ADMIN))
3425+
goto bad_unshare_out;
3426+
}
3427+
34143428
err = check_unshare_flags(unshare_flags);
34153429
if (err)
34163430
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 };
@@ -1623,6 +1626,15 @@ static struct ctl_table kern_table[] = {
16231626
.mode = 0644,
16241627
.proc_handler = proc_dointvec,
16251628
},
1629+
#ifdef CONFIG_USER_NS
1630+
{
1631+
.procname = "unprivileged_userns_clone",
1632+
.data = &unprivileged_userns_clone,
1633+
.maxlen = sizeof(int),
1634+
.mode = 0644,
1635+
.proc_handler = proc_dointvec,
1636+
},
1637+
#endif
16261638
#ifdef CONFIG_PROC_SYSCTL
16271639
{
16281640
.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)