diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-04-07 08:44:00 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-04-08 03:38:19 +0900 |
commit | 2c5f119c3cc78bd7da0c7c56b57eca43bac464c1 (patch) | |
tree | 3dfc4b4d0996e3511bc98e158327f4fad0b6f1ee /src/libsystemd/sd-device | |
parent | 733b7bfd79a9bf7c46e8930ca5f235507aeed6fc (diff) | |
download | systemd-2c5f119c3cc78bd7da0c7c56b57eca43bac464c1.tar.gz |
sd-device,udev: refuse invalid devlink and store in normalized form
This is especially for the case that the path contains "..".
Prompted by https://github.com/systemd/systemd/pull/27164#issuecomment-1498863858.
This also makes SYMLINK= gracefully handle paths prefixed with "/dev/",
and manage devlink paths with path_hash_ops.
Diffstat (limited to 'src/libsystemd/sd-device')
-rw-r--r-- | src/libsystemd/sd-device/device-private.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-device/sd-device.c | 36 |
2 files changed, 31 insertions, 7 deletions
diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index 740c58438c..b903d1afd6 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -38,7 +38,7 @@ void device_set_db_persist(sd_device *device); void device_set_devlink_priority(sd_device *device, int priority); int device_ensure_usec_initialized(sd_device *device, sd_device *device_old); int device_add_devlink(sd_device *device, const char *devlink); -void device_remove_devlink(sd_device *device, const char *devlink); +int device_remove_devlink(sd_device *device, const char *devlink); bool device_has_devlink(sd_device *device, const char *devlink); int device_add_property(sd_device *device, const char *property, const char *value); int device_add_propertyf(sd_device *device, const char *key, const char *format, ...) _printf_(3, 4); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index e86ec3e75b..2a5defca65 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1473,34 +1473,58 @@ int device_add_tag(sd_device *device, const char *tag, bool both) { return 0; } +static char *prefix_dev(const char *p) { + assert(p); + + if (path_startswith(p, "/dev/")) + return strdup(p); + + return path_join("/dev/", p); +} + int device_add_devlink(sd_device *device, const char *devlink) { + char *p; int r; assert(device); assert(devlink); - r = set_put_strdup(&device->devlinks, devlink); + if (!path_is_safe(devlink)) + return -EINVAL; + + p = prefix_dev(devlink); + if (!p) + return -ENOMEM; + + path_simplify(p); + + r = set_ensure_consume(&device->devlinks, &path_hash_ops_free, p); if (r < 0) return r; device->devlinks_generation++; device->property_devlinks_outdated = true; - return 0; + return r; /* return 1 when newly added, 0 when already exists */ } -void device_remove_devlink(sd_device *device, const char *devlink) { - _cleanup_free_ char *s = NULL; +int device_remove_devlink(sd_device *device, const char *devlink) { + _cleanup_free_ char *p = NULL, *s = NULL; assert(device); assert(devlink); - s = set_remove(device->devlinks, devlink); + p = prefix_dev(devlink); + if (!p) + return -ENOMEM; + + s = set_remove(device->devlinks, p); if (!s) - return; + return 0; /* does not exist */ device->devlinks_generation++; device->property_devlinks_outdated = true; + return 1; /* removed */ } bool device_has_devlink(sd_device *device, const char *devlink) { |