Skip to content

Commit

Permalink
Merge branch 'userns-fixes' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/luto/linux

Pull user-namespace fixes from Andy Lutomirski.

* 'userns-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux:
  userns: Changing any namespace id mappings should require privileges
  userns: Check uid_map's opener's fsuid, not the current fsuid
  userns: Don't let unprivileged users trick privileged users into setting the id_map
  • Loading branch information
torvalds committed Apr 19, 2013
2 parents a86d526 + 41c21e3 commit 6835039
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions kernel/user_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

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);

static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
Expand Down Expand Up @@ -612,10 +613,10 @@ static ssize_t map_write(struct file *file, const char __user *buf,
if (map->nr_extents != 0)
goto out;

/* Require the appropriate privilege CAP_SETUID or CAP_SETGID
* over the user namespace in order to set the id mapping.
/*
* Adjusting namespace settings requires capabilities on the target.
*/
if (cap_valid(cap_setid) && !ns_capable(ns, cap_setid))
if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
goto out;

/* Get a buffer */
Expand Down Expand Up @@ -700,7 +701,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,

ret = -EPERM;
/* 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;

/* Map the lower ids from the parent user namespace to the
Expand Down Expand Up @@ -787,20 +788,21 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t
&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)
{
/* Allow mapping to your own filesystem ids */
if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) {
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, current_fsuid()))
if (uid_eq(uid, file->f_cred->fsuid))
return true;
}
else if (cap_setid == CAP_SETGID) {
kgid_t gid = make_kgid(ns->parent, id);
if (gid_eq(gid, current_fsgid()))
if (gid_eq(gid, file->f_cred->fsgid))
return true;
}
}
Expand All @@ -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
* (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 false;
Expand Down

0 comments on commit 6835039

Please sign in to comment.