diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index f2f349f2ac..27aa6bf2fc 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -16,6 +16,7 @@ int device_get_property_bool(sd_device *device, const char *key); int device_get_property_int(sd_device *device, const char *key, int *ret); int device_get_property_uint(sd_device *device, const char *key, unsigned *ret); int device_get_ifname(sd_device *device, const char **ret); +int device_get_sysattr_safe_string(sd_device *device, const char *sysattr, const char **ret); int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value); int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value); static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 307137b431..09a48a74c5 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -2619,6 +2619,34 @@ _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, return sd_device_get_sysattr_value_with_size(device, sysattr, ret_value, NULL); } +int device_get_sysattr_safe_string(sd_device *device, const char *sysattr, const char **ret) { + const char *value; + int r; + + r = sd_device_get_sysattr_value(device, sysattr, &value); + if (r < 0) + return r; + + if (!string_is_safe(value, + STRING_ALLOW_EMPTY | + STRING_ALLOW_NEWLINES | + STRING_ALLOW_BACKSLASHES | + STRING_ALLOW_QUOTES | + STRING_ALLOW_GLOBS)) { + if (DEBUG_LOGGING) { + _cleanup_free_ char *escaped = cescape(value); + log_device_debug(device, "sd-device: '%s' sysattr contains invalid characters, refusing: %s", + sysattr, strnull(escaped)); + } + return -ENXIO; + } + + if (ret) + *ret = value; + + return 0; +} + int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value) { const char *value; int r; diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index bf62e9082b..9201919898 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -305,6 +305,13 @@ static void test_sd_device_one(sd_device *d) { ASSERT_OK(r = device_get_sysattr_unsigned(d, "nsid", &x)); ASSERT_EQ(x > 0, r > 0); } + + const char *uevent; + if (sd_device_get_sysattr_value(d, "uevent", &uevent) >= 0) { + const char *uevent_safe; + ASSERT_OK(device_get_sysattr_safe_string(d, "uevent", &uevent_safe)); + ASSERT_STREQ(uevent, uevent_safe); + } } static void exclude_problematic_devices(sd_device_enumerator *e) {