|
|
|
@ -286,7 +286,7 @@ EXPORT_SYMBOL(from_kuid_munged); |
|
|
|
|
/**
|
|
|
|
|
* make_kgid - Map a user-namespace gid pair into a kgid. |
|
|
|
|
* @ns: User namespace that the gid is in |
|
|
|
|
* @uid: group identifier |
|
|
|
|
* @gid: group identifier |
|
|
|
|
* |
|
|
|
|
* Maps a user-namespace gid pair into a kernel internal kgid, |
|
|
|
|
* and returns that kgid. |
|
|
|
@ -482,7 +482,8 @@ static int projid_m_show(struct seq_file *seq, void *v) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void *m_start(struct seq_file *seq, loff_t *ppos, struct uid_gid_map *map) |
|
|
|
|
static void *m_start(struct seq_file *seq, loff_t *ppos, |
|
|
|
|
struct uid_gid_map *map) |
|
|
|
|
{ |
|
|
|
|
struct uid_gid_extent *extent = NULL; |
|
|
|
|
loff_t pos = *ppos; |
|
|
|
@ -546,7 +547,8 @@ struct seq_operations proc_projid_seq_operations = { |
|
|
|
|
.show = projid_m_show, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static bool mappings_overlap(struct uid_gid_map *new_map, struct uid_gid_extent *extent) |
|
|
|
|
static bool mappings_overlap(struct uid_gid_map *new_map, |
|
|
|
|
struct uid_gid_extent *extent) |
|
|
|
|
{ |
|
|
|
|
u32 upper_first, lower_first, upper_last, lower_last; |
|
|
|
|
unsigned idx; |
|
|
|
@ -653,7 +655,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, |
|
|
|
|
ret = -EINVAL; |
|
|
|
|
pos = kbuf; |
|
|
|
|
new_map.nr_extents = 0; |
|
|
|
|
for (;pos; pos = next_line) { |
|
|
|
|
for (; pos; pos = next_line) { |
|
|
|
|
extent = &new_map.extent[new_map.nr_extents]; |
|
|
|
|
|
|
|
|
|
/* Find the end of line and ensure I don't look past it */ |
|
|
|
@ -687,13 +689,16 @@ static ssize_t map_write(struct file *file, const char __user *buf, |
|
|
|
|
|
|
|
|
|
/* Verify we have been given valid starting values */ |
|
|
|
|
if ((extent->first == (u32) -1) || |
|
|
|
|
(extent->lower_first == (u32) -1 )) |
|
|
|
|
(extent->lower_first == (u32) -1)) |
|
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
/* Verify count is not zero and does not cause the extent to wrap */ |
|
|
|
|
/* Verify count is not zero and does not cause the
|
|
|
|
|
* extent to wrap |
|
|
|
|
*/ |
|
|
|
|
if ((extent->first + extent->count) <= extent->first) |
|
|
|
|
goto out; |
|
|
|
|
if ((extent->lower_first + extent->count) <= extent->lower_first) |
|
|
|
|
if ((extent->lower_first + extent->count) <= |
|
|
|
|
extent->lower_first) |
|
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
/* Do the ranges in extent overlap any previous extents? */ |
|
|
|
@ -751,7 +756,8 @@ out: |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ssize_t proc_uid_map_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos) |
|
|
|
|
ssize_t proc_uid_map_write(struct file *file, const char __user *buf, |
|
|
|
|
size_t size, loff_t *ppos) |
|
|
|
|
{ |
|
|
|
|
struct seq_file *seq = file->private_data; |
|
|
|
|
struct user_namespace *ns = seq->private; |
|
|
|
@ -767,7 +773,8 @@ ssize_t proc_uid_map_write(struct file *file, const char __user *buf, size_t siz |
|
|
|
|
&ns->uid_map, &ns->parent->uid_map); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ssize_t proc_gid_map_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos) |
|
|
|
|
ssize_t proc_gid_map_write(struct file *file, const char __user *buf, |
|
|
|
|
size_t size, loff_t *ppos) |
|
|
|
|
{ |
|
|
|
|
struct seq_file *seq = file->private_data; |
|
|
|
|
struct user_namespace *ns = seq->private; |
|
|
|
@ -783,7 +790,8 @@ ssize_t proc_gid_map_write(struct file *file, const char __user *buf, size_t siz |
|
|
|
|
&ns->gid_map, &ns->parent->gid_map); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos) |
|
|
|
|
ssize_t proc_projid_map_write(struct file *file, const char __user *buf, |
|
|
|
|
size_t size, loff_t *ppos) |
|
|
|
|
{ |
|
|
|
|
struct seq_file *seq = file->private_data; |
|
|
|
|
struct user_namespace *ns = seq->private; |
|
|
|
@ -800,7 +808,7 @@ 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(const struct file *file,
|
|
|
|
|
static bool new_idmap_permitted(const struct file *file, |
|
|
|
|
struct user_namespace *ns, int cap_setid, |
|
|
|
|
struct uid_gid_map *new_map) |
|
|
|
|
{ |
|
|
|
@ -811,8 +819,7 @@ static bool new_idmap_permitted(const struct file *file, |
|
|
|
|
kuid_t uid = make_kuid(ns->parent, id); |
|
|
|
|
if (uid_eq(uid, file->f_cred->fsuid)) |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else if (cap_setid == CAP_SETGID) { |
|
|
|
|
} else if (cap_setid == CAP_SETGID) { |
|
|
|
|
kgid_t gid = make_kgid(ns->parent, id); |
|
|
|
|
if (gid_eq(gid, file->f_cred->fsgid)) |
|
|
|
|
return true; |
|
|
|
|