26223f
From: "Eric W. Biederman" <ebiederm@xmission.com>
26223f
Date: Wed, 26 Nov 2014 23:22:14 -0600
26223f
Subject: [PATCH] userns: Only allow the creator of the userns unprivileged
26223f
 mappings
26223f
26223f
If you did not create the user namespace and are allowed
26223f
to write to uid_map or gid_map you should already have the necessary
26223f
privilege in the parent user namespace to establish any mapping
26223f
you want so this will not affect userspace in practice.
26223f
26223f
Limiting unprivileged uid mapping establishment to the creator of the
26223f
user namespace makes it easier to verify all credentials obtained with
26223f
the uid mapping can be obtained without the uid mapping without
26223f
privilege.
26223f
26223f
Limiting unprivileged gid mapping establishment (which is temporarily
26223f
absent) to the creator of the user namespace also ensures that the
26223f
combination of uid and gid can already be obtained without privilege.
26223f
26223f
This is part of the fix for CVE-2014-8989.
26223f
26223f
Cc: stable@vger.kernel.org
26223f
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
26223f
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
26223f
---
26223f
 kernel/user_namespace.c | 6 ++++--
26223f
 1 file changed, 4 insertions(+), 2 deletions(-)
26223f
26223f
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
26223f
index 9451b12a9b6c..1e34de2fbd60 100644
26223f
--- a/kernel/user_namespace.c
26223f
+++ b/kernel/user_namespace.c
26223f
@@ -812,14 +812,16 @@ static bool new_idmap_permitted(const struct file *file,
26223f
 				struct user_namespace *ns, int cap_setid,
26223f
 				struct uid_gid_map *new_map)
26223f
 {
26223f
+	const struct cred *cred = file->f_cred;
26223f
 	/* Don't allow mappings that would allow anything that wouldn't
26223f
 	 * be allowed without the establishment of unprivileged mappings.
26223f
 	 */
26223f
-	if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) {
26223f
+	if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1) &&
26223f
+	    uid_eq(ns->owner, cred->euid)) {
26223f
 		u32 id = new_map->extent[0].lower_first;
26223f
 		if (cap_setid == CAP_SETUID) {
26223f
 			kuid_t uid = make_kuid(ns->parent, id);
26223f
-			if (uid_eq(uid, file->f_cred->euid))
26223f
+			if (uid_eq(uid, cred->euid))
26223f
 				return true;
26223f
 		}
26223f
 	}
26223f
-- 
26223f
2.1.0
26223f