summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoonas Niilola <juippis@gentoo.org>2021-05-09 12:27:30 +0300
committerJoonas Niilola <juippis@gentoo.org>2021-05-10 08:01:28 +0300
commitfb00aa98de17dba7ffb4ef5fed6608af8a6968d8 (patch)
tree1fe0efc8da92c68fecd8bc06c61d9b4beec458d1 /app-emulation/lxc/files
parentdev-ruby/rails: add ruby27 (diff)
downloadgentoo-fb00aa98de17dba7ffb4ef5fed6608af8a6968d8.tar.gz
gentoo-fb00aa98de17dba7ffb4ef5fed6608af8a6968d8.tar.bz2
gentoo-fb00aa98de17dba7ffb4ef5fed6608af8a6968d8.zip
app-emulation/lxc: handle kernels with CAP_SETFCAP
Closes: https://bugs.gentoo.org/789012 Signed-off-by: Joonas Niilola <juippis@gentoo.org>
Diffstat (limited to 'app-emulation/lxc/files')
-rw-r--r--app-emulation/lxc/files/lxc-4.0.9-handle-kernels-with-CAP_SETFCAP.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/app-emulation/lxc/files/lxc-4.0.9-handle-kernels-with-CAP_SETFCAP.patch b/app-emulation/lxc/files/lxc-4.0.9-handle-kernels-with-CAP_SETFCAP.patch
new file mode 100644
index 000000000000..6fba3c4154a4
--- /dev/null
+++ b/app-emulation/lxc/files/lxc-4.0.9-handle-kernels-with-CAP_SETFCAP.patch
@@ -0,0 +1,93 @@
+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 {