diff options
| -rw-r--r-- | kernel/user_namespace.c | 22 |
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 | ||
| 26 | static struct kmem_cache *user_ns_cachep __read_mostly; | 26 | static struct kmem_cache *user_ns_cachep __read_mostly; |
| 27 | 27 | ||
| 28 | static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, | 28 | static 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 | ||
| 31 | static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) | 32 | static 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 | ||
| 790 | static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, | 791 | static 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; |
