diff options
Diffstat (limited to 'app-emulation/lxc/files/lxc-2.1.1-cgroups-enable-container-without-CAP_SYS_ADMIN.patch')
-rw-r--r-- | app-emulation/lxc/files/lxc-2.1.1-cgroups-enable-container-without-CAP_SYS_ADMIN.patch | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/app-emulation/lxc/files/lxc-2.1.1-cgroups-enable-container-without-CAP_SYS_ADMIN.patch b/app-emulation/lxc/files/lxc-2.1.1-cgroups-enable-container-without-CAP_SYS_ADMIN.patch new file mode 100644 index 000000000000..8493491d0d65 --- /dev/null +++ b/app-emulation/lxc/files/lxc-2.1.1-cgroups-enable-container-without-CAP_SYS_ADMIN.patch @@ -0,0 +1,164 @@ +From b635e92d21d2a4d71a553388f18cfa08f44bf1ba Mon Sep 17 00:00:00 2001 +From: Christian Brauner <christian.brauner@ubuntu.com> +Date: Mon, 30 Oct 2017 14:16:46 +0100 +Subject: [PATCH] cgroups: enable container without CAP_SYS_ADMIN + +In case cgroup namespaces are supported but we do not have CAP_SYS_ADMIN we +need to mount cgroups for the container. This patch enables both privileged and +unprivileged containers without CAP_SYS_ADMIN. + +Closes #1737. + +Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com> +--- + src/lxc/cgroups/cgfs.c | 3 ++- + src/lxc/cgroups/cgfsng.c | 52 +++++++++++++++++++++++++++++++++++++++++++++--- + src/lxc/cgroups/cgroup.c | 2 +- + src/lxc/conf.c | 3 --- + src/lxc/conf.h | 1 + + 5 files changed, 53 insertions(+), 8 deletions(-) + +diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c +index bcbd6613..efd627f0 100644 +--- a/src/lxc/cgroups/cgfs.c ++++ b/src/lxc/cgroups/cgfs.c +@@ -1418,11 +1418,12 @@ static bool cgroupfs_mount_cgroup(void *hdata, const char *root, int type) + struct cgfs_data *cgfs_d; + struct cgroup_process_info *info, *base_info; + int r, saved_errno = 0; ++ struct lxc_handler *handler = hdata; + + if (cgns_supported()) + return true; + +- cgfs_d = hdata; ++ cgfs_d = handler->cgroup_data; + if (!cgfs_d) + return false; + base_info = cgfs_d->info; +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index e43edd7d..ec6440c1 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -50,6 +50,7 @@ + #include <linux/types.h> + #include <linux/kdev_t.h> + ++#include "caps.h" + #include "cgroup.h" + #include "cgroup_utils.h" + #include "commands.h" +@@ -1616,17 +1617,49 @@ do_secondstage_mounts_if_needed(int type, struct hierarchy *h, + return 0; + } + ++static int mount_cgroup_cgns_supported(struct hierarchy *h, const char *controllerpath) ++{ ++ int ret; ++ char *controllers = NULL; ++ char *type = "cgroup2"; ++ ++ if (!h->is_cgroup_v2) { ++ controllers = lxc_string_join(",", (const char **)h->controllers, false); ++ if (!controllers) ++ return -ENOMEM; ++ type = "cgroup"; ++ } ++ ++ ret = mount("cgroup", controllerpath, type, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RELATIME, controllers); ++ free(controllers); ++ if (ret < 0) { ++ SYSERROR("Failed to mount %s with cgroup filesystem type %s", controllerpath, type); ++ return -1; ++ } ++ ++ DEBUG("Mounted %s with cgroup filesystem type %s", controllerpath, type); ++ return 0; ++} ++ + static bool cgfsng_mount(void *hdata, const char *root, int type) + { +- struct cgfsng_handler_data *d = hdata; ++ int i; + char *tmpfspath = NULL; + bool retval = false; +- int i; ++ struct lxc_handler *handler = hdata; ++ struct cgfsng_handler_data *d = handler->cgroup_data; ++ bool has_cgns = false, has_sys_admin = true; + + if ((type & LXC_AUTO_CGROUP_MASK) == 0) + return true; + +- if (cgns_supported()) ++ has_cgns = cgns_supported(); ++ if (!lxc_list_empty(&handler->conf->keepcaps)) ++ has_sys_admin = in_caplist(CAP_SYS_ADMIN, &handler->conf->keepcaps); ++ else ++ has_sys_admin = !in_caplist(CAP_SYS_ADMIN, &handler->conf->caps); ++ ++ if (has_cgns && has_sys_admin) + return true; + + tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL); +@@ -1662,6 +1695,19 @@ static bool cgfsng_mount(void *hdata, const char *root, int type) + free(controllerpath); + goto bad; + } ++ ++ if (has_cgns && !has_sys_admin) { ++ /* If cgroup namespaces are supported but the container ++ * will not have CAP_SYS_ADMIN after it has started we ++ * need to mount the cgroups manually. ++ */ ++ r = mount_cgroup_cgns_supported(h, controllerpath); ++ free(controllerpath); ++ if (r < 0) ++ goto bad; ++ continue; ++ } ++ + if (mount_cgroup_full(type, h, controllerpath, d->container_cgroup) < 0) { + free(controllerpath); + goto bad; +diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c +index 674e3090..36a665b1 100644 +--- a/src/lxc/cgroups/cgroup.c ++++ b/src/lxc/cgroups/cgroup.c +@@ -166,7 +166,7 @@ bool cgroup_chown(struct lxc_handler *handler) + bool cgroup_mount(const char *root, struct lxc_handler *handler, int type) + { + if (ops) +- return ops->mount_cgroup(handler->cgroup_data, root, type); ++ return ops->mount_cgroup(handler, root, type); + + return false; + } +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index d2fab945..44d97843 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -210,9 +210,6 @@ __thread struct lxc_conf *current_config; + struct lxc_conf *current_config; + #endif + +-/* Declare this here, since we don't want to reshuffle the whole file. */ +-static int in_caplist(int cap, struct lxc_list *caps); +- + static struct mount_opt mount_opt[] = { + { "async", 1, MS_SYNCHRONOUS }, + { "atime", 1, MS_NOATIME }, +diff --git a/src/lxc/conf.h b/src/lxc/conf.h +index c61f861e..63e71e2d 100644 +--- a/src/lxc/conf.h ++++ b/src/lxc/conf.h +@@ -402,5 +402,6 @@ extern unsigned long add_required_remount_flags(const char *s, const char *d, + unsigned long flags); + extern int run_script(const char *name, const char *section, const char *script, + ...); ++extern int in_caplist(int cap, struct lxc_list *caps); + + #endif /* __LXC_CONF_H */ +-- +2.13.6 + |