You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/app-emulation/lxc/files/lxc-4.0.9-handle-kernels-wi...

94 lines
3.4 KiB

From 91ad9b94bcd964adfbaa8d84d8f39304d39835d0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner@ubuntu.com>
Date: Thu, 6 May 2021 18:16:45 +0200
Subject: [PATCH] conf: handle kernels with CAP_SETFCAP
LXC is being very clever and sometimes maps the caller's uid into the
child userns. This means that the caller can technically write fscaps
that are valid in the ancestor userns (which can be a security issue in
some scenarios) so newer kernels require CAP_SETFCAP to do this. Until
newuidmap/newgidmap are updated to account for this simply write the
mapping directly in this case.
Cc: stable-4.0
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
src/lxc/conf.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 72e21b5300..f388946970 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2978,6 +2978,9 @@ static int lxc_map_ids_exec_wrapper(void *args)
return -1;
}
+static struct id_map *find_mapped_hostid_entry(const struct lxc_list *idmap,
+ unsigned id, enum idtype idtype);
+
int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
{
int fill, left;
@@ -2991,12 +2994,22 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
char mapbuf[STRLITERALLEN("new@idmap") + STRLITERALLEN(" ") +
INTTYPE_TO_STRLEN(pid_t) + STRLITERALLEN(" ") +
LXC_IDMAPLEN] = {0};
- bool had_entry = false, use_shadow = false;
+ bool had_entry = false, maps_host_root = false, use_shadow = false;
int hostuid, hostgid;
hostuid = geteuid();
hostgid = getegid();
+ /*
+ * Check whether caller wants to map host root.
+ * Due to a security fix newer kernels require CAP_SETFCAP when mapping
+ * host root into the child userns as you would be able to write fscaps
+ * that would be valid in the ancestor userns. Mapping host root should
+ * rarely be the case but LXC is being clever in a bunch of cases.
+ */
+ if (find_mapped_hostid_entry(idmap, 0, ID_TYPE_UID))
+ maps_host_root = true;
+
/* If new{g,u}idmap exists, that is, if shadow is handing out subuid
* ranges, then insist that root also reserve ranges in subuid. This
* will protected it by preventing another user from being handed the
@@ -3014,7 +3027,9 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
else if (!gidmap)
WARN("newgidmap is lacking necessary privileges");
- if (uidmap > 0 && gidmap > 0) {
+ if (maps_host_root) {
+ INFO("Caller maps host root. Writing mapping directly");
+ } else if (uidmap > 0 && gidmap > 0) {
DEBUG("Functional newuidmap and newgidmap binary found");
use_shadow = true;
} else {
@@ -4229,14 +4244,14 @@ static struct id_map *mapped_nsid_add(const struct lxc_conf *conf, unsigned id,
return retmap;
}
-static struct id_map *find_mapped_hostid_entry(const struct lxc_conf *conf,
+static struct id_map *find_mapped_hostid_entry(const struct lxc_list *idmap,
unsigned id, enum idtype idtype)
{
struct id_map *map;
struct lxc_list *it;
struct id_map *retmap = NULL;
- lxc_list_for_each (it, &conf->id_map) {
+ lxc_list_for_each (it, idmap) {
map = it->elem;
if (map->idtype != idtype)
continue;
@@ -4265,7 +4280,7 @@ static struct id_map *mapped_hostid_add(const struct lxc_conf *conf, uid_t id,
return NULL;
/* Reuse existing mapping. */
- tmp = find_mapped_hostid_entry(conf, id, type);
+ tmp = find_mapped_hostid_entry(&conf->id_map, id, type);
if (tmp) {
memcpy(entry, tmp, sizeof(*entry));
} else {