Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a76f00a

Browse files
hallynheftig
authored andcommitted
add sysctl to allow disabling unprivileged CLONE_NEWUSER
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. [bwh: Remove unneeded binary sysctl bits] [bwh: Keep this sysctl, but change the default to enabled] [heftig: correct commit subject to reduce confusion]
1 parent 1037d3a commit a76f00a

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

kernel/fork.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@
122122

123123
#include <kunit/visibility.h>
124124

125+
#ifdef CONFIG_USER_NS
126+
extern int unprivileged_userns_clone;
127+
#else
128+
#define unprivileged_userns_clone 0
129+
#endif
130+
125131
/*
126132
* Minimum number of threads to boot the kernel
127133
*/
@@ -1933,6 +1939,10 @@ __latent_entropy struct task_struct *copy_process(
19331939
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
19341940
return ERR_PTR(-EINVAL);
19351941

1942+
if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
1943+
if (!capable(CAP_SYS_ADMIN))
1944+
return ERR_PTR(-EPERM);
1945+
19361946
/*
19371947
* Thread groups must share signals as well, and detached threads
19381948
* can only be started up within the thread group.
@@ -3099,6 +3109,12 @@ int ksys_unshare(unsigned long unshare_flags)
30993109
if (unshare_flags & CLONE_NEWNS)
31003110
unshare_flags |= CLONE_FS;
31013111

3112+
if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
3113+
err = -EPERM;
3114+
if (!capable(CAP_SYS_ADMIN))
3115+
goto bad_unshare_out;
3116+
}
3117+
31023118
err = check_unshare_flags(unshare_flags);
31033119
if (err)
31043120
goto bad_unshare_out;

kernel/sysctl.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ EXPORT_SYMBOL_GPL(sysctl_long_vals);
7777
static const int ngroups_max = NGROUPS_MAX;
7878
static const int cap_last_cap = CAP_LAST_CAP;
7979

80+
#ifdef CONFIG_USER_NS
81+
extern int unprivileged_userns_clone;
82+
#endif
83+
8084
#ifdef CONFIG_PROC_SYSCTL
8185

8286
/**
@@ -1581,6 +1585,15 @@ int proc_do_static_key(const struct ctl_table *table, int write,
15811585
}
15821586

15831587
static const struct ctl_table kern_table[] = {
1588+
#ifdef CONFIG_USER_NS
1589+
{
1590+
.procname = "unprivileged_userns_clone",
1591+
.data = &unprivileged_userns_clone,
1592+
.maxlen = sizeof(int),
1593+
.mode = 0644,
1594+
.proc_handler = proc_dointvec,
1595+
},
1596+
#endif
15841597
#ifdef CONFIG_PROC_SYSCTL
15851598
{
15861599
.procname = "tainted",

kernel/user_namespace.c

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

25+
/* sysctl */
26+
int unprivileged_userns_clone = 1;
27+
2528
static struct kmem_cache *user_ns_cachep __ro_after_init;
2629
static DEFINE_MUTEX(userns_state_mutex);
2730

0 commit comments

Comments
 (0)