aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-04-18 21:09:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-18 21:09:12 -0400
commit6835039d7ed618bbac0c8c18d62d3e030b162d37 (patch)
tree840f453cebdb1a908d3b40dfbcb9e42699636055 /kernel
parenta86d52667d8eda5de39393ce737794403bdce1eb (diff)
parent41c21e351e79004dbb4efa4bc14a53a7e0af38c5 (diff)
Merge branch 'userns-fixes' of git://git.kernel.org/pub/scm/linux/kernel/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
Diffstat (limited to 'kernel')
-rw-r--r--kernel/user_namespace.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index a54f26f82eb2..e134d8f365dd 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -25,7 +25,8 @@
25 25
26static struct kmem_cache *user_ns_cachep __read_mostly; 26static struct kmem_cache *user_ns_cachep __read_mostly;
27 27
28static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, 28static bool new_idmap_permitted(const struct file *file,
29 struct user_namespace *ns, int cap_setid,
29 struct uid_gid_map *map); 30 struct uid_gid_map *map);
30 31
31static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) 32static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
@@ -612,10 +613,10 @@ static ssize_t map_write(struct file *file, const char __user *buf,
612 if (map->nr_extents != 0) 613 if (map->nr_extents != 0)
613 goto out; 614 goto out;
614 615
615 /* Require the appropriate privilege CAP_SETUID or CAP_SETGID 616 /*
616 * over the user namespace in order to set the id mapping. 617 * Adjusting namespace settings requires capabilities on the target.
617 */ 618 */
618 if (cap_valid(cap_setid) && !ns_capable(ns, cap_setid)) 619 if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
619 goto out; 620 goto out;
620 621
621 /* Get a buffer */ 622 /* Get a buffer */
@@ -700,7 +701,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
700 701
701 ret = -EPERM; 702 ret = -EPERM;
702 /* Validate the user is allowed to use user id's mapped to. */ 703 /* Validate the user is allowed to use user id's mapped to. */
703 if (!new_idmap_permitted(ns, cap_setid, &new_map)) 704 if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
704 goto out; 705 goto out;
705 706
706 /* Map the lower ids from the parent user namespace to the 707 /* 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 &ns->projid_map, &ns->parent->projid_map); 788 &ns->projid_map, &ns->parent->projid_map);
788} 789}
789 790
790static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, 791static bool new_idmap_permitted(const struct file *file,
792 struct user_namespace *ns, int cap_setid,
791 struct uid_gid_map *new_map) 793 struct uid_gid_map *new_map)
792{ 794{
793 /* Allow mapping to your own filesystem ids */ 795 /* Allow mapping to your own filesystem ids */
@@ -795,12 +797,12 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
795 u32 id = new_map->extent[0].lower_first; 797 u32 id = new_map->extent[0].lower_first;
796 if (cap_setid == CAP_SETUID) { 798 if (cap_setid == CAP_SETUID) {
797 kuid_t uid = make_kuid(ns->parent, id); 799 kuid_t uid = make_kuid(ns->parent, id);
798 if (uid_eq(uid, current_fsuid())) 800 if (uid_eq(uid, file->f_cred->fsuid))
799 return true; 801 return true;
800 } 802 }
801 else if (cap_setid == CAP_SETGID) { 803 else if (cap_setid == CAP_SETGID) {
802 kgid_t gid = make_kgid(ns->parent, id); 804 kgid_t gid = make_kgid(ns->parent, id);
803 if (gid_eq(gid, current_fsgid())) 805 if (gid_eq(gid, file->f_cred->fsgid))
804 return true; 806 return true;
805 } 807 }
806 } 808 }
@@ -811,8 +813,10 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
811 813
812 /* Allow the specified ids if we have the appropriate capability 814 /* Allow the specified ids if we have the appropriate capability
813 * (CAP_SETUID or CAP_SETGID) over the parent user namespace. 815 * (CAP_SETUID or CAP_SETGID) over the parent user namespace.
816 * And the opener of the id file also had the approprpiate capability.
814 */ 817 */
815 if (ns_capable(ns->parent, cap_setid)) 818 if (ns_capable(ns->parent, cap_setid) &&
819 file_ns_capable(file, ns->parent, cap_setid))
816 return true; 820 return true;
817 821
818 return false; 822 return false;