1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-31 16:21:26 +03:00

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 .
This commit is contained in:
Christian Brauner 2017-11-22 17:20:35 +01:00
parent bfbcf21d75
commit e07aefbd67
No known key found for this signature in database
GPG Key ID: 7B3C391EFEA93624

View File

@ -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;
}