Commit 6708075f authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Andy Lutomirski

userns: Don't let unprivileged users trick privileged users into setting the id_map

When we require privilege for setting /proc/<pid>/uid_map or
/proc/<pid>/gid_map no longer allow an unprivileged user to
open the file and pass it to a privileged program to write
to the file.

Instead when privilege is required require both the opener and the
writer to have the necessary capabilities.

I have tested this code and verified that setting /proc/<pid>/uid_map
fails when an unprivileged user opens the file and a privielged user
attempts to set the mapping, that unprivileged users can still map
their own id, and that a privileged users can still setup an arbitrary
mapping.
Reported-by: default avatarAndy Lutomirski <luto@amacapital.net>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarAndy Lutomirski <luto@amacapital.net>
parent 6c4c4d4b
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
static struct kmem_cache *user_ns_cachep __read_mostly; static struct kmem_cache *user_ns_cachep __read_mostly;
static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid,
struct uid_gid_map *map); struct uid_gid_map *map);
static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
...@@ -700,7 +701,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, ...@@ -700,7 +701,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
ret = -EPERM; ret = -EPERM;
/* Validate the user is allowed to use user id's mapped to. */ /* Validate the user is allowed to use user id's mapped to. */
if (!new_idmap_permitted(ns, cap_setid, &new_map)) if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
goto out; goto out;
/* Map the lower ids from the parent user namespace to the /* Map the lower ids from the parent user namespace to the
...@@ -787,7 +788,8 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t ...@@ -787,7 +788,8 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t
&ns->projid_map, &ns->parent->projid_map); &ns->projid_map, &ns->parent->projid_map);
} }
static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, static bool new_idmap_permitted(const struct file *file,
struct user_namespace *ns, int cap_setid,
struct uid_gid_map *new_map) struct uid_gid_map *new_map)
{ {
/* Allow mapping to your own filesystem ids */ /* Allow mapping to your own filesystem ids */
...@@ -811,8 +813,10 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, ...@@ -811,8 +813,10 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
/* Allow the specified ids if we have the appropriate capability /* Allow the specified ids if we have the appropriate capability
* (CAP_SETUID or CAP_SETGID) over the parent user namespace. * (CAP_SETUID or CAP_SETGID) over the parent user namespace.
* And the opener of the id file also had the approprpiate capability.
*/ */
if (ns_capable(ns->parent, cap_setid)) if (ns_capable(ns->parent, cap_setid) &&
file_ns_capable(file, ns->parent, cap_setid))
return true; return true;
return false; return false;
......
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