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