diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index adf20b68c7..a9538310be 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; }