From e5e053bbb72681e16560cfe9d1f24bf8e63e522e Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 8 May 2023 14:38:41 +0800 Subject: [PATCH] libsensors: Avoid non-symlink sysfs device entries Devices under the MMC / SDIO bus have a "device" entry that is not a symbolic link; instead it contains the device ID of the SDIO device. This causes the sysfs parsing code in libsensors to error out, as it expects all "device" entries be symbolic links to the underlying device. Check for non-symlink entries before calling realpath() to avoid using it as a valid device link. Signed-off-by: Chen-Yu Tsai --- lib/sysfs.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/sysfs.c b/lib/sysfs.c index 9516cec4..ad8f1696 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -700,6 +700,26 @@ static int classify_device(const char *dev_name, return ret; } +/* realpath(3) that returns NULL for a path that isn't a symlink. + This is needed to deal with devices that have a "device" sysfs + entry that has the device ID, such as SDIO devices. */ +static char* realpath_no_symlink(const char *restrict path, + char *restrict resolved_path) +{ + struct stat st; + int ret; + + if (lstat(path, &st) < 0) + return NULL; + + if (!S_ISLNK(st.st_mode)) { + errno = -EINVAL; + return NULL; + } + + return realpath(path, resolved_path); +} + static int find_bus_type(const char *dev_path, const char *dev_name, sensors_chip_features *entry) @@ -740,7 +760,7 @@ static int find_bus_type(const char *dev_path, if (!ret) { snprintf(linkpath, NAME_MAX, "%s/device", my_dev_path); free(my_dev_path); - my_dev_path = realpath(linkpath, NULL); + my_dev_path = realpath_no_symlink(linkpath, NULL); if (my_dev_path != NULL) dev_name = strrchr(my_dev_path, '/') + 1; else if (errno == ENOMEM) @@ -838,7 +858,7 @@ static int sensors_add_hwmon_device(const char *path, const char *classdev) (void)classdev; /* hide warning */ snprintf(linkpath, NAME_MAX, "%s/device", path); - dev_path = realpath(linkpath, NULL); + dev_path = realpath_no_symlink(linkpath, NULL); if (dev_path == NULL) { if (errno == ENOMEM) { sensors_fatal_error(__func__, "Out of memory");