From: Lennart Poettering Date: Mon, 11 Apr 2022 20:02:23 +0000 (+0200) Subject: sd-device: use chase_symlinks() O_PATH fd X-Git-Tag: v251-rc2~131^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1793bb611249b9525f6ed17964347d377d97e494;p=thirdparty%2Fsystemd.git sd-device: use chase_symlinks() O_PATH fd chase_symlinks() can return its last O_PATH fd to us. Let's use that and make the access() check a bit tighter by going via faccessat() on the O_PATH fd. This doesn't really change too much, but is nice in context of the next commit, which uses the O_PATH fd in one other way. --- diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index d31526fc222..eb50f592b7f 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -150,7 +150,9 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { _syspath); if (verify) { - r = chase_symlinks(_syspath, NULL, 0, &syspath, NULL); + _cleanup_close_ int fd = -1; + + r = chase_symlinks(_syspath, NULL, 0, &syspath, &fd); if (r == -ENOENT) /* the device does not exist (any more?) */ return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), @@ -181,25 +183,28 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { path_simplify(syspath); } - if (path_startswith(syspath, "/sys/devices/")) { - char *path; + if (path_startswith(syspath, "/sys/devices/")) { + /* For proper devices, stricter rules apply: they must have a 'uevent' file, + * otherwise we won't allow them */ - /* all 'devices' require an 'uevent' file */ - path = strjoina(syspath, "/uevent"); - if (access(path, F_OK) < 0) { + if (faccessat(fd, "uevent", F_OK, 0) < 0) { if (errno == ENOENT) - /* This is not a valid device. - * Note, this condition is quite often satisfied when - * enumerating devices or finding a parent device. + /* This is not a valid device. Note, this condition is quite often + * satisfied when enumerating devices or finding a parent device. * Hence, use log_trace_errno() here. */ return log_trace_errno(SYNTHETIC_ERRNO(ENODEV), - "sd-device: the uevent file \"%s\" does not exist.", path); + "sd-device: the uevent file \"%s/uevent\" does not exist.", syspath); - return log_debug_errno(errno, "sd-device: cannot access uevent file for %s: %m", syspath); + return log_debug_errno(errno, "sd-device: cannot find uevent file for %s: %m", syspath); } } else { - /* everything else just needs to be a directory */ - if (!is_dir(syspath, false)) + struct stat st; + + /* For everything else lax rules apply: they just need to be a directory */ + + if (fstat(fd, &st) < 0) + return log_debug_errno(errno, "sd-device: failed to check if syspath \"%s\" is a directory: %m", syspath); + if (!S_ISDIR(st.st_mode)) return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "sd-device: the syspath \"%s\" is not a directory.", syspath); }