summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.patch164
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
+