From: Yu Watanabe Date: Mon, 8 Aug 2022 14:19:49 +0000 (+0900) Subject: sd-device-enumerator: FOREACH_DEVICE_PROPERTY() does not provide NULL value X-Git-Tag: v252-rc1~491^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b07131facff9a6937e595caa2c4f020586ba98a5;p=thirdparty%2Fsystemd.git sd-device-enumerator: FOREACH_DEVICE_PROPERTY() does not provide NULL value Hence, when sd_device_enumerator_add_match_property() called with NULL for value, then the filter always unmatches with the device. --- diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index 1f18b843f21..01d45a941f9 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -157,7 +157,7 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer else hashmap = &enumerator->nomatch_sysattr; - r = update_match_strv(hashmap, sysattr, value); + r = update_match_strv(hashmap, sysattr, value, /* clear_on_null = */ true); if (r <= 0) return r; @@ -172,9 +172,7 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume assert_return(enumerator, -EINVAL); assert_return(property, -EINVAL); - /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called - * multiple times with the same property but different value. */ - r = hashmap_put_strdup_full(&enumerator->match_property, &trivial_hash_ops_free_free, property, value); + r = update_match_strv(&enumerator->match_property, property, value, /* clear_on_null = */ false); if (r <= 0) return r; @@ -464,29 +462,25 @@ int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *de } static bool match_property(sd_device_enumerator *enumerator, sd_device *device) { - const char *property; - const char *value; + const char *property_pattern; + char * const *value_patterns; assert(enumerator); assert(device); + /* Unlike device_match_sysattr(), this accepts device that has at least one matching property. */ + if (hashmap_isempty(enumerator->match_property)) return true; - HASHMAP_FOREACH_KEY(value, property, enumerator->match_property) { - const char *property_dev, *value_dev; - - FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) { - if (fnmatch(property, property_dev, 0) != 0) - continue; - - if (!value && !value_dev) - return true; + HASHMAP_FOREACH_KEY(value_patterns, property_pattern, enumerator->match_property) { + const char *property, *value; - if (!value || !value_dev) + FOREACH_DEVICE_PROPERTY(device, property, value) { + if (fnmatch(property_pattern, property, 0) != 0) continue; - if (fnmatch(value, value_dev, 0) == 0) + if (strv_fnmatch(value_patterns, value)) return true; } } diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c index 98163058be5..459dbdf4e49 100644 --- a/src/libsystemd/sd-device/device-monitor.c +++ b/src/libsystemd/sd-device/device-monitor.c @@ -787,7 +787,7 @@ _public_ int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor *m, co hashmap = &m->nomatch_sysattr_filter; /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */ - return update_match_strv(hashmap, sysattr, value); + return update_match_strv(hashmap, sysattr, value, /* clear_on_null = */ true); } _public_ int sd_device_monitor_filter_add_match_parent(sd_device_monitor *m, sd_device *device, int match) { diff --git a/src/libsystemd/sd-device/device-util.c b/src/libsystemd/sd-device/device-util.c index e2209a0b609..3b8689e0d65 100644 --- a/src/libsystemd/sd-device/device-util.c +++ b/src/libsystemd/sd-device/device-util.c @@ -5,7 +5,7 @@ #include "device-util.h" #include "path-util.h" -int update_match_strv(Hashmap **match_strv, const char *key, const char *value) { +int update_match_strv(Hashmap **match_strv, const char *key, const char *value, bool clear_on_null) { char **strv; int r; @@ -17,7 +17,7 @@ int update_match_strv(Hashmap **match_strv, const char *key, const char *value) if (!value) { char **v; - if (strv_isempty(strv)) + if (strv_isempty(strv) || !clear_on_null) return 0; /* Accept all value. Clear previous assignment. */ diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index 6dae8ef6f2f..d9e9f1e8c4a 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -82,6 +82,6 @@ #define log_device_warning_errno(device, error, ...) log_device_full_errno(device, LOG_WARNING, error, __VA_ARGS__) #define log_device_error_errno(device, error, ...) log_device_full_errno(device, LOG_ERR, error, __VA_ARGS__) -int update_match_strv(Hashmap **match_strv, const char *key, const char *value); +int update_match_strv(Hashmap **match_strv, const char *key, const char *value, bool clear_on_null); bool device_match_sysattr(sd_device *device, Hashmap *match_sysattr, Hashmap *nomatch_sysattr); bool device_match_parent(sd_device *device, Set *match_parent, Set *nomatch_parent);