Commit 5b80ce31 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Luis Henriques

userns: Only allow the creator of the userns unprivileged mappings

commit f95d7918 upstream.

If you did not create the user namespace and are allowed
to write to uid_map or gid_map you should already have the necessary
privilege in the parent user namespace to establish any mapping
you want so this will not affect userspace in practice.

Limiting unprivileged uid mapping establishment to the creator of the
user namespace makes it easier to verify all credentials obtained with
the uid mapping can be obtained without the uid mapping without
privilege.

Limiting unprivileged gid mapping establishment (which is temporarily
absent) to the creator of the user namespace also ensures that the
combination of uid and gid can already be obtained without privilege.

This is part of the fix for CVE-2014-8989.
Reviewed-by: default avatarAndy Lutomirski <luto@amacapital.net>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent ce8670ce
...@@ -812,14 +812,16 @@ static bool new_idmap_permitted(const struct file *file, ...@@ -812,14 +812,16 @@ static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid, struct user_namespace *ns, int cap_setid,
struct uid_gid_map *new_map) struct uid_gid_map *new_map)
{ {
const struct cred *cred = file->f_cred;
/* Don't allow mappings that would allow anything that wouldn't /* Don't allow mappings that would allow anything that wouldn't
* be allowed without the establishment of unprivileged mappings. * be allowed without the establishment of unprivileged mappings.
*/ */
if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) { if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1) &&
uid_eq(ns->owner, cred->euid)) {
u32 id = new_map->extent[0].lower_first; u32 id = new_map->extent[0].lower_first;
if (cap_setid == CAP_SETUID) { if (cap_setid == CAP_SETUID) {
kuid_t uid = make_kuid(ns->parent, id); kuid_t uid = make_kuid(ns->parent, id);
if (uid_eq(uid, file->f_cred->euid)) if (uid_eq(uid, cred->euid))
return true; return true;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment