File: add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch

package info (click to toggle)
linux 6.16.8-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,724,600 kB
  • sloc: ansic: 26,562,026; asm: 271,344; sh: 144,033; python: 72,469; makefile: 57,130; perl: 36,821; xml: 19,553; cpp: 5,820; yacc: 4,915; lex: 2,955; awk: 1,667; sed: 28; ruby: 25
file content (101 lines) | stat: -rw-r--r-- 2,913 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Fri, 31 May 2013 19:12:12 +0000 (+0100)
Subject: add sysctl to disallow unprivileged CLONE_NEWUSER by default
Origin: http://kernel.ubuntu.com/git?p=serge%2Fubuntu-saucy.git;a=commit;h=5c847404dcb2e3195ad0057877e1422ae90892b8

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]
---
 kernel/fork.c           | 16 ++++++++++++++++
 kernel/sysctl.c         | 13 +++++++++++++
 kernel/user_namespace.c |  3 +++
 3 files changed, 32 insertions(+)

--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -122,6 +122,12 @@
 
 #include <kunit/visibility.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
  */
@@ -1933,6 +1939,10 @@ __latent_entropy struct task_struct *cop
 	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.
@@ -3099,6 +3109,12 @@ int ksys_unshare(unsigned long unshare_f
 	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;
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -77,6 +77,10 @@ EXPORT_SYMBOL_GPL(sysctl_long_vals);
 static const int ngroups_max = NGROUPS_MAX;
 static const int cap_last_cap = CAP_LAST_CAP;
 
+#ifdef CONFIG_USER_NS
+extern int unprivileged_userns_clone;
+#endif
+
 #ifdef CONFIG_PROC_SYSCTL
 
 /**
@@ -1581,6 +1585,15 @@ int proc_do_static_key(const struct ctl_
 }
 
 static const struct ctl_table kern_table[] = {
+#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",
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -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);