aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2014-11-26 23:22:14 -0600
committerJiri Slaby <jslaby@suse.cz>2015-01-07 17:55:13 +0100
commit42eec84f58cde5309a5dd770c42f3e364f05f3e0 (patch)
tree6657d1575bf3c56b470a9617c759b865ac485155 /kernel
parent6cffb2520aba06a0df8ddbe0917175e07475431a (diff)
userns: Only allow the creator of the userns unprivileged mappings
commit f95d7918bd1e724675de4940039f2865e5eec5fe 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: Andy Lutomirski <luto@amacapital.net> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/user_namespace.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 6e495bd672a7..c2ca6c01e575 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -798,14 +798,16 @@ static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid,
struct uid_gid_map *new_map)
{
+ const struct cred *cred = file->f_cred;
/* Don't allow mappings that would allow anything that wouldn't
* 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;
if (cap_setid == CAP_SETUID) {
kuid_t uid = make_kuid(ns->parent, id);
- if (uid_eq(uid, file->f_cred->euid))
+ if (uid_eq(uid, cred->euid))
return true;
}
}