aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/user_namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/user_namespace.c')
-rw-r--r--kernel/user_namespace.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index b14f4d342043..d8c30db06c5b 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -9,7 +9,7 @@
9#include <linux/nsproxy.h> 9#include <linux/nsproxy.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <linux/user_namespace.h> 11#include <linux/user_namespace.h>
12#include <linux/proc_fs.h> 12#include <linux/proc_ns.h>
13#include <linux/highuid.h> 13#include <linux/highuid.h>
14#include <linux/cred.h> 14#include <linux/cred.h>
15#include <linux/securebits.h> 15#include <linux/securebits.h>
@@ -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)
@@ -61,6 +62,15 @@ int create_user_ns(struct cred *new)
61 kgid_t group = new->egid; 62 kgid_t group = new->egid;
62 int ret; 63 int ret;
63 64
65 /*
66 * Verify that we can not violate the policy of which files
67 * may be accessed that is specified by the root directory,
68 * by verifing that the root directory is at the root of the
69 * mount namespace which allows all files to be accessed.
70 */
71 if (current_chrooted())
72 return -EPERM;
73
64 /* The creator needs a mapping in the parent user namespace 74 /* The creator needs a mapping in the parent user namespace
65 * or else we won't be able to reasonably tell userspace who 75 * or else we won't be able to reasonably tell userspace who
66 * created a user_namespace. 76 * created a user_namespace.
@@ -87,6 +97,8 @@ int create_user_ns(struct cred *new)
87 97
88 set_cred_user_ns(new, ns); 98 set_cred_user_ns(new, ns);
89 99
100 update_mnt_policy(ns);
101
90 return 0; 102 return 0;
91} 103}
92 104
@@ -601,10 +613,10 @@ static ssize_t map_write(struct file *file, const char __user *buf,
601 if (map->nr_extents != 0) 613 if (map->nr_extents != 0)
602 goto out; 614 goto out;
603 615
604 /* Require the appropriate privilege CAP_SETUID or CAP_SETGID 616 /*
605 * over the user namespace in order to set the id mapping. 617 * Adjusting namespace settings requires capabilities on the target.
606 */ 618 */
607 if (cap_valid(cap_setid) && !ns_capable(ns, cap_setid)) 619 if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
608 goto out; 620 goto out;
609 621
610 /* Get a buffer */ 622 /* Get a buffer */
@@ -689,7 +701,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
689 701
690 ret = -EPERM; 702 ret = -EPERM;
691 /* 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. */
692 if (!new_idmap_permitted(ns, cap_setid, &new_map)) 704 if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
693 goto out; 705 goto out;
694 706
695 /* Map the lower ids from the parent user namespace to the 707 /* Map the lower ids from the parent user namespace to the
@@ -776,7 +788,8 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t
776 &ns->projid_map, &ns->parent->projid_map); 788 &ns->projid_map, &ns->parent->projid_map);
777} 789}
778 790
779static 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,
780 struct uid_gid_map *new_map) 793 struct uid_gid_map *new_map)
781{ 794{
782 /* Allow mapping to your own filesystem ids */ 795 /* Allow mapping to your own filesystem ids */
@@ -784,12 +797,12 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
784 u32 id = new_map->extent[0].lower_first; 797 u32 id = new_map->extent[0].lower_first;
785 if (cap_setid == CAP_SETUID) { 798 if (cap_setid == CAP_SETUID) {
786 kuid_t uid = make_kuid(ns->parent, id); 799 kuid_t uid = make_kuid(ns->parent, id);
787 if (uid_eq(uid, current_fsuid())) 800 if (uid_eq(uid, file->f_cred->fsuid))
788 return true; 801 return true;
789 } 802 }
790 else if (cap_setid == CAP_SETGID) { 803 else if (cap_setid == CAP_SETGID) {
791 kgid_t gid = make_kgid(ns->parent, id); 804 kgid_t gid = make_kgid(ns->parent, id);
792 if (gid_eq(gid, current_fsgid())) 805 if (gid_eq(gid, file->f_cred->fsgid))
793 return true; 806 return true;
794 } 807 }
795 } 808 }
@@ -800,8 +813,10 @@ static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid,
800 813
801 /* Allow the specified ids if we have the appropriate capability 814 /* Allow the specified ids if we have the appropriate capability
802 * (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.
803 */ 817 */
804 if (ns_capable(ns->parent, cap_setid)) 818 if (ns_capable(ns->parent, cap_setid) &&
819 file_ns_capable(file, ns->parent, cap_setid))
805 return true; 820 return true;
806 821
807 return false; 822 return false;