Revert "capabilities: require CAP_SETFCAP to map uid 0"

This reverts commit fb4c1c2e9f.

Fixes the ABI issues in 5.10.35 that at the moment, we can't handle due
to the KABI freeze.  These are not patches that mean much for android
systems, and will be reverted the next KABI "reset" point.

Bug: 161946584
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I7b12040440bc2bedfbabc71d60339cb843e59570
This commit is contained in:
Greg Kroah-Hartman 2021-05-08 13:12:03 +02:00
parent 0ddd59c5da
commit d9d0c09e0a
3 changed files with 4 additions and 67 deletions

View File

@ -65,9 +65,6 @@ struct user_namespace {
kgid_t group;
struct ns_common ns;
unsigned long flags;
/* parent_could_setfcap: true if the creator if this ns had CAP_SETFCAP
* in its effective capability set at the child ns creation time. */
bool parent_could_setfcap;
#ifdef CONFIG_KEYS
/* List of joinable keyrings in this namespace. Modification access of

View File

@ -333,8 +333,7 @@ struct vfs_ns_cap_data {
#define CAP_AUDIT_CONTROL 30
/* Set or remove capabilities on files.
Map uid=0 into a child user namespace. */
/* Set or remove capabilities on files */
#define CAP_SETFCAP 31

View File

@ -106,7 +106,6 @@ int create_user_ns(struct cred *new)
if (!ns)
goto fail_dec;
ns->parent_could_setfcap = cap_raised(new->cap_effective, CAP_SETFCAP);
ret = ns_alloc_inum(&ns->ns);
if (ret)
goto fail_free;
@ -842,60 +841,6 @@ static int sort_idmaps(struct uid_gid_map *map)
return 0;
}
/**
* verify_root_map() - check the uid 0 mapping
* @file: idmapping file
* @map_ns: user namespace of the target process
* @new_map: requested idmap
*
* If a process requests mapping parent uid 0 into the new ns, verify that the
* process writing the map had the CAP_SETFCAP capability as the target process
* will be able to write fscaps that are valid in ancestor user namespaces.
*
* Return: true if the mapping is allowed, false if not.
*/
static bool verify_root_map(const struct file *file,
struct user_namespace *map_ns,
struct uid_gid_map *new_map)
{
int idx;
const struct user_namespace *file_ns = file->f_cred->user_ns;
struct uid_gid_extent *extent0 = NULL;
for (idx = 0; idx < new_map->nr_extents; idx++) {
if (new_map->nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
extent0 = &new_map->extent[idx];
else
extent0 = &new_map->forward[idx];
if (extent0->lower_first == 0)
break;
extent0 = NULL;
}
if (!extent0)
return true;
if (map_ns == file_ns) {
/* The process unshared its ns and is writing to its own
* /proc/self/uid_map. User already has full capabilites in
* the new namespace. Verify that the parent had CAP_SETFCAP
* when it unshared.
* */
if (!file_ns->parent_could_setfcap)
return false;
} else {
/* Process p1 is writing to uid_map of p2, who is in a child
* user namespace to p1's. Verify that the opener of the map
* file has CAP_SETFCAP against the parent of the new map
* namespace */
if (!file_ns_capable(file, map_ns->parent, CAP_SETFCAP))
return false;
}
return true;
}
static ssize_t map_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos,
int cap_setid,
@ -903,7 +848,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
struct uid_gid_map *parent_map)
{
struct seq_file *seq = file->private_data;
struct user_namespace *map_ns = seq->private;
struct user_namespace *ns = seq->private;
struct uid_gid_map new_map;
unsigned idx;
struct uid_gid_extent extent;
@ -950,7 +895,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
/*
* Adjusting namespace settings requires capabilities on the target.
*/
if (cap_valid(cap_setid) && !file_ns_capable(file, map_ns, CAP_SYS_ADMIN))
if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
goto out;
/* Parse the user data */
@ -1020,7 +965,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(file, map_ns, cap_setid, &new_map))
if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
goto out;
ret = -EPERM;
@ -1141,10 +1086,6 @@ static bool new_idmap_permitted(const struct file *file,
struct uid_gid_map *new_map)
{
const struct cred *cred = file->f_cred;
if (cap_setid == CAP_SETUID && !verify_root_map(file, ns, new_map))
return false;
/* Don't allow mappings that would allow anything that wouldn't
* be allowed without the establishment of unprivileged mappings.
*/