]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device: don't accept non-sysfs paths
authorLennart Poettering <lennart@poettering.net>
Mon, 11 Apr 2022 20:04:06 +0000 (22:04 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 13 Apr 2022 12:40:13 +0000 (14:40 +0200)
There are some file systems mounted below /sys/ that are not actually
sysfs, i.e. are not arranged in a sysfs/kobject style. Let's refuse
those early. (Example, /sys/fs/cgroup/ and similar.)

(Also, let's add an env var for this, so that it can be turned off for
test cases.)

docs/ENVIRONMENT.md
src/libsystemd/sd-device/sd-device.c
test/udev-test.pl

index 0cbe5cfb6bca7c70a7a085bfcd359a5ab39d7786..5f02f888a5ed3a8f61d4b981ecca5a4a82c0c490 100644 (file)
@@ -199,7 +199,7 @@ All tools:
   or whenever they change if it wants to integrate with `systemd-logind`'s
   APIs.
 
-`systemd-udevd`:
+`systemd-udevd` and sd-device library:
 
 * `$NET_NAMING_SCHEME=` — if set, takes a network naming scheme (i.e. one of
   "v238", "v239", "v240"…, or the special value "latest") as parameter. If
@@ -211,6 +211,10 @@ All tools:
   prefixed with `:` in which case the kernel command line option takes
   precedence, if it is specified as well.
 
+* `$SYSTEMD_DEVICE_VERIFY_SYSFS` — if set to "0", disables verification that
+  devices sysfs path are actually backed by sysfs. Relaxing this verification
+  is useful for testing purposes.
+
 `nss-systemd`:
 
 * `$SYSTEMD_NSS_BYPASS_SYNTHETIC=1` — if set, `nss-systemd` won't synthesize
index eb50f592b7f4ba0769214f447860a9e41756a6bb..0435beca16e1ae28b3beb04b142b3d12735d0f5b 100644 (file)
@@ -13,6 +13,7 @@
 #include "device-private.h"
 #include "device-util.h"
 #include "dirent-util.h"
+#include "env-util.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "format-util.h"
@@ -20,6 +21,7 @@
 #include "hashmap.h"
 #include "id128-util.h"
 #include "macro.h"
+#include "missing_magic.h"
 #include "netlink-util.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -208,6 +210,21 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
                                 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
                                                        "sd-device: the syspath \"%s\" is not a directory.", syspath);
                 }
+
+                /* Only operate on sysfs, i.e. refuse going down into /sys/fs/cgroup/ or similar places where
+                 * things are not arranged as kobjects in kernel, and hence don't necessarily have
+                 * kobject/attribute structure. */
+                r = getenv_bool_secure("SYSTEMD_DEVICE_VERIFY_SYSFS");
+                if (r < 0 && r != -ENXIO)
+                        log_debug_errno(r, "Failed to parse $SYSTEMD_DEVICE_VERIFY_SYSFS value: %m");
+                if (r != 0) {
+                        r = fd_is_fs_type(fd, SYSFS_MAGIC);
+                        if (r < 0)
+                                return log_debug_errno(r, "sd-device: failed to check if syspath \"%s\" is backed by sysfs.", syspath);
+                        if (r == 0)
+                                return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
+                                                       "sd-device: the syspath \"%s\" is outside of sysfs, refusing.", syspath);
+                }
         } else {
                 syspath = strdup(_syspath);
                 if (!syspath)
index 3aeac655780f5b6810252941a3c71bf848f9adfa..802bc1f3de886b96566e01866ea65989ef2a4aee 100755 (executable)
@@ -33,6 +33,10 @@ BEGIN {
     }
 }
 
+# Relax sd-device's sysfs verification, since we want to provide a fake sysfs
+# here that actually is a tmpfs.
+$ENV{"SYSTEMD_DEVICE_VERIFY_SYSFS"}="0";
+
 my $udev_bin            = "./test-udev";
 my $valgrind            = 0;
 my $gdb                 = 0;