5428b6
From c225bc59b8907de11f389bd8efb82155ccde75a7 Mon Sep 17 00:00:00 2001
5428b6
From: Richard Purdie <richard.purdie@linuxfoundation.org>
5428b6
Date: Tue, 16 Feb 2021 12:17:36 +0000
5428b6
Subject: [PATCH] proc: dont trigger mount error with invalid options on old
5428b6
 kernels
5428b6
5428b6
As of commit 4e39995371738b04d98d27b0d34ea8fe09ec9fab ("core: introduce
5428b6
ProtectProc= and ProcSubset= to expose hidepid= and subset= procfs
5428b6
mount options") kernels older than v5.8 generate multple warnings at
5428b6
boot, as seen in this Yocto build from today:
5428b6
5428b6
     qemux86-64 login: root
5428b6
     [   65.829009] proc: Bad value for 'hidepid'
5428b6
     root@qemux86-64:~# dmesg|grep proc:
5428b6
     [   16.990706] proc: Bad value for 'hidepid'
5428b6
     [   28.060178] proc: Bad value for 'hidepid'
5428b6
     [   28.874229] proc: Bad value for 'hidepid'
5428b6
     [   32.685107] proc: Bad value for 'hidepid'
5428b6
     [   65.829009] proc: Bad value for 'hidepid'
5428b6
     root@qemux86-64:~#
5428b6
5428b6
We see reports of the issue as in general its hard to someone to tell
5428b6
the difference between an error in dmesg which they should worry about and
5428b6
one that is harmless. This adds support burden to developers so Yocto
5428b6
Project has added this patch.
5428b6
5428b6
The commit that triggers this is systemd v247-rc1~378^2~3 -- so any
5428b6
systemd 247 and above plus kernel v5.7 or older will need this.
5428b6
5428b6
As noted in https://github.com/systemd/systemd/issues/16896
5428b6
it is possible changes could be backported to different kernel versions
5428b6
so the test isn't 100% foolproof but does give better results than a
5428b6
continual stream of bug reports.
5428b6
5428b6
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
5428b6
---
5428b6
 src/core/namespace.c | 22 ++++++++++++++++++++--
5428b6
 1 file changed, 20 insertions(+), 2 deletions(-)
5428b6
5428b6
diff --git a/src/core/namespace.c b/src/core/namespace.c
5428b6
index 4ed0991b56d1..3fa2d4e9d640 100644
5428b6
--- a/src/core/namespace.c
5428b6
+++ b/src/core/namespace.c
5428b6
@@ -4,7 +4,9 @@
5428b6
 #include <linux/loop.h>
5428b6
 #include <sched.h>
5428b6
 #include <stdio.h>
5428b6
+#include <stdlib.h>
5428b6
 #include <sys/mount.h>
5428b6
+#include <sys/utsname.h>
5428b6
 #include <unistd.h>
5428b6
 #include <linux/fs.h>
5428b6
 
5428b6
@@ -881,12 +883,28 @@ static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
5428b6
         _cleanup_free_ char *opts = NULL;
5428b6
         const char *entry_path;
5428b6
         int r, n;
5428b6
+        struct utsname uts;
5428b6
+        bool old = false;
5428b6
 
5428b6
         assert(m);
5428b6
         assert(ns_info);
5428b6
 
5428b6
-        if (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
5428b6
-            ns_info->proc_subset != PROC_SUBSET_ALL) {
5428b6
+        /* If uname says that the system is older than v5.8, then the textual hidepid= stuff is not
5428b6
+         * supported by the kernel, and thus the per-instance hidepid= neither, which means we
5428b6
+         * really don't want to use it, since it would affect our host's /proc * mount. Hence let's
5428b6
+         * gracefully fallback to a classic, unrestricted version. */
5428b6
+
5428b6
+        r = uname(&uts;;
5428b6
+        if (r < 0)
5428b6
+               return -errno;
5428b6
+
5428b6
+        if (strverscmp(uts.release, "5.8") < 0) {
5428b6
+                log_debug("Pre v5.8 kernel detected [v%s] - skipping hidepid=", uts.release);
5428b6
+                old = true;
5428b6
+        }
5428b6
+
5428b6
+        if (!old && (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
5428b6
+            ns_info->proc_subset != PROC_SUBSET_ALL)) {
5428b6
 
5428b6
                 /* Starting with kernel 5.8 procfs' hidepid= logic is truly per-instance (previously it
5428b6
                  * pretended to be per-instance but actually was per-namespace), hence let's make use of it