From: Christian Brauner Date: Wed, 22 Nov 2017 16:20:35 +0000 (+0100) Subject: cgroup: check whether unified hierarchy is writable X-Git-Tag: v236~146^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e07aefbd675b651f8d45b5fb458f2747b04d6e04;p=thirdparty%2Fsystemd.git cgroup: check whether unified hierarchy is writable When systemd is running inside a container employing user namespaces it currently mounts the unified cgroup hierarchy without being able to write to it. This causes systemd to freeze during boot. This patch checks whether the unified cgroup hierarchy is writable. If it is not it will not mount it. This solution is based on a patch by Evgeny Vereshchagin. Closes #6408. Closes https://github.com/lxc/lxc/issues/1678 . --- diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index adf20b68c77..a9538310be5 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -29,6 +29,7 @@ #include "cgroup-util.h" #include "dev-setup.h" #include "efivars.h" +#include "fileio.h" #include "fs-util.h" #include "label.h" #include "log.h" @@ -46,9 +47,10 @@ #include "virt.h" typedef enum MountMode { - MNT_NONE = 0, - MNT_FATAL = 1 << 0, - MNT_IN_CONTAINER = 1 << 1, + MNT_NONE = 0, + MNT_FATAL = 1 << 0, + MNT_IN_CONTAINER = 1 << 1, + MNT_CHECK_WRITABLE = 1 << 2, } MountMode; typedef struct MountPoint { @@ -103,9 +105,9 @@ static const MountPoint mount_table[] = { { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER }, { "cgroup", "/sys/fs/cgroup/unified", "cgroup2", "nsdelegate", MS_NOSUID|MS_NOEXEC|MS_NODEV, - cg_is_hybrid_wanted, MNT_IN_CONTAINER }, + cg_is_hybrid_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE }, { "cgroup", "/sys/fs/cgroup/unified", "cgroup2", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, - cg_is_hybrid_wanted, MNT_IN_CONTAINER }, + cg_is_hybrid_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE }, { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd,xattr", MS_NOSUID|MS_NOEXEC|MS_NODEV, cg_is_legacy_wanted, MNT_IN_CONTAINER }, { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, @@ -202,6 +204,14 @@ static int mount_one(const MountPoint *p, bool relabel) { if (relabel) (void) label_fix(p->where, false, false); + if (p->mode & MNT_CHECK_WRITABLE) { + r = access(p->where, W_OK); + if (r < 0) { + (void) umount(p->where); + return (p->mode & MNT_FATAL) ? r : 0; + } + } + return 1; }