| From 1707b9959e67e5e73987e1ff8a72189d24656fa0 Mon Sep 17 00:00:00 2001 |
| From: Krzysztof Nowicki <krzysztof.a.nowicki+github@gmail.com> |
| Date: Wed, 28 Mar 2018 13:36:33 +0200 |
| Subject: [PATCH] core: dont't remount /sys/fs/cgroup for relabel if not needed |
| (#8595) |
| |
| The initial fix for relabelling the cgroup filesystem for |
| SELinux delivered in commit 8739f23e3 was based on the assumption that |
| the cgroup filesystem is already populated once mount_setup() is |
| executed, which was true for my system. What I wasn't aware is that this |
| is the case only when another instance of systemd was running before |
| this one, which can happen if systemd is used in the initrd (for ex. by |
| dracut). |
| |
| In case of a clean systemd start-up the cgroup filesystem is actually |
| being populated after mount_setup() and does not need relabelling as at |
| that moment the SELinux policy is already loaded. Since however the root |
| cgroup filesystem was remounted read-only in the meantime this operation |
| will now fail. |
| |
| To fix this check for the filesystem mount flags before relabelling and |
| only remount ro->rw->ro if necessary and leave the filesystem read-write |
| otherwise. |
| |
| Fixes #7901. |
| |
| (cherry picked from commit 6f7729c1767998110c4460c85c94435c5782a613) |
| |
| src/core/mount-setup.c | 35 ++++++++++++++++++++++++++++++----- |
| 1 file changed, 30 insertions(+), 5 deletions(-) |
| |
| diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c |
| index 7a2cae4a3..ed493cbe3 100644 |
| |
| |
| @@ -25,6 +25,8 @@ |
| #include <stdlib.h> |
| #include <string.h> |
| #include <assert.h> |
| +#include <sys/statfs.h> |
| +#include <sys/statvfs.h> |
| #include <unistd.h> |
| #include <ftw.h> |
| |
| @@ -337,6 +339,31 @@ static int nftw_cb( |
| |
| return FTW_CONTINUE; |
| }; |
| + |
| +static int relabel_cgroup_filesystems(void) { |
| + int r; |
| + struct statfs st; |
| + |
| + /* Temporarily remount the root cgroup filesystem to give it a proper label. Do this |
| + only when the filesystem has been already populated by a previous instance of systemd |
| + running from initrd. Otherwise don't remount anything and leave the filesystem read-write |
| + for the cgroup filesystems to be mounted inside. */ |
| + r = statfs("/sys/fs/cgroup", &st); |
| + if (r < 0) { |
| + return log_error_errno(errno, "Failed to determine mount flags for /sys/fs/cgroup: %m"); |
| + } |
| + |
| + if (st.f_flags & ST_RDONLY) |
| + (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL); |
| + |
| + (void) label_fix("/sys/fs/cgroup", false, false); |
| + nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); |
| + |
| + if (st.f_flags & ST_RDONLY) |
| + (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL); |
| + |
| + return 0; |
| +} |
| #endif |
| |
| int mount_setup(bool loaded_policy) { |
| @@ -369,11 +396,9 @@ int mount_setup(bool loaded_policy) { |
| nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); |
| nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); |
| |
| - /* Temporarily remount the root cgroup filesystem to give it a proper label. */ |
| - (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL); |
| - label_fix("/sys/fs/cgroup", false, false); |
| - nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); |
| - (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL); |
| + r = relabel_cgroup_filesystems(); |
| + if (r < 0) |
| + return r; |
| |
| after_relabel = now(CLOCK_MONOTONIC); |
| |