summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-device
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-04-07 08:44:00 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-04-08 03:38:19 +0900
commit2c5f119c3cc78bd7da0c7c56b57eca43bac464c1 (patch)
tree3dfc4b4d0996e3511bc98e158327f4fad0b6f1ee /src/libsystemd/sd-device
parent733b7bfd79a9bf7c46e8930ca5f235507aeed6fc (diff)
downloadsystemd-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.h2
-rw-r--r--src/libsystemd/sd-device/sd-device.c36
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) {