aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-12-14 10:55:36 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-12-14 19:12:03 -0500
commit5e4a08476b50fa39210fca82e03325cc46b9c235 (patch)
treefb3a3c6b4c3f613abf354adefcff8a74051acdce /kernel
parent520d9eabce18edfef76a60b7b839d54facafe1f9 (diff)
userns: Require CAP_SYS_ADMIN for most uses of setns.
Andy Lutomirski <luto@amacapital.net> found a nasty little bug in the permissions of setns. With unprivileged user namespaces it became possible to create new namespaces without privilege. However the setns calls were relaxed to only require CAP_SYS_ADMIN in the user nameapce of the targed namespace. Which made the following nasty sequence possible. pid = clone(CLONE_NEWUSER | CLONE_NEWNS); if (pid == 0) { /* child */ system("mount --bind /home/me/passwd /etc/passwd"); } else if (pid != 0) { /* parent */ char path[PATH_MAX]; snprintf(path, sizeof(path), "/proc/%u/ns/mnt"); fd = open(path, O_RDONLY); setns(fd, 0); system("su -"); } Prevent this possibility by requiring CAP_SYS_ADMIN in the current user namespace when joing all but the user namespace. Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/pid_namespace.c3
-rw-r--r--kernel/utsname.c3
2 files changed, 4 insertions, 2 deletions
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 560da0dab230..fdbd0cdf271a 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -325,7 +325,8 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns)
325 struct pid_namespace *active = task_active_pid_ns(current); 325 struct pid_namespace *active = task_active_pid_ns(current);
326 struct pid_namespace *ancestor, *new = ns; 326 struct pid_namespace *ancestor, *new = ns;
327 327
328 if (!ns_capable(new->user_ns, CAP_SYS_ADMIN)) 328 if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) ||
329 !nsown_capable(CAP_SYS_ADMIN))
329 return -EPERM; 330 return -EPERM;
330 331
331 /* 332 /*
diff --git a/kernel/utsname.c b/kernel/utsname.c
index f6336d51d64c..08b197e8c485 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -113,7 +113,8 @@ static int utsns_install(struct nsproxy *nsproxy, void *new)
113{ 113{
114 struct uts_namespace *ns = new; 114 struct uts_namespace *ns = new;
115 115
116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) 116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
117 !nsown_capable(CAP_SYS_ADMIN))
117 return -EPERM; 118 return -EPERM;
118 119
119 get_uts_ns(ns); 120 get_uts_ns(ns);