commit:     fb00aa98de17dba7ffb4ef5fed6608af8a6968d8
Author:     Joonas Niilola <juippis <AT> gentoo <DOT> org>
AuthorDate: Sun May  9 09:27:30 2021 +0000
Commit:     Joonas Niilola <juippis <AT> gentoo <DOT> org>
CommitDate: Mon May 10 05:01:28 2021 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=fb00aa98

app-emulation/lxc: handle kernels with CAP_SETFCAP

Closes: https://bugs.gentoo.org/789012
Signed-off-by: Joonas Niilola <juippis <AT> gentoo.org>

 ...lxc-4.0.9-handle-kernels-with-CAP_SETFCAP.patch | 93 ++++++++++++++++++++++
 .../lxc/{lxc-4.0.9.ebuild => lxc-4.0.9-r1.ebuild}  |  1 +
 2 files changed, 94 insertions(+)

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 00000000000..6fba3c4154a
--- /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 <[email protected]>
+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 <[email protected]>
+---
+ 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 {

diff --git a/app-emulation/lxc/lxc-4.0.9.ebuild 
b/app-emulation/lxc/lxc-4.0.9-r1.ebuild
similarity index 98%
rename from app-emulation/lxc/lxc-4.0.9.ebuild
rename to app-emulation/lxc/lxc-4.0.9-r1.ebuild
index 89a0b2e2b2d..8fbfeda5aca 100644
--- a/app-emulation/lxc/lxc-4.0.9.ebuild
+++ b/app-emulation/lxc/lxc-4.0.9-r1.ebuild
@@ -72,6 +72,7 @@ pkg_setup() {
 }
 
 PATCHES=(
+       "${FILESDIR}"/lxc-4.0.9-handle-kernels-with-CAP_SETFCAP.patch # bug 
789012
        "${FILESDIR}"/${PN}-3.0.0-bash-completion.patch
        "${FILESDIR}"/${PN}-2.0.5-omit-sysconfig.patch # bug 558854
 )

Reply via email to