From: Lennart Poettering Date: Mon, 11 Apr 2022 20:04:06 +0000 (+0200) Subject: sd-device: don't accept non-sysfs paths X-Git-Tag: v251-rc2~131^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a7910612a5be324d8b6994a2f7e1a2edb63ad03c;p=thirdparty%2Fsystemd.git sd-device: don't accept non-sysfs paths 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.) --- diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 0cbe5cfb6bc..5f02f888a5e 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -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 diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index eb50f592b7f..0435beca16e 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -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) diff --git a/test/udev-test.pl b/test/udev-test.pl index 3aeac655780..802bc1f3de8 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -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;