From d2b81326ac46cf4a66dcf58a6855bfee49b0b989 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 12 Oct 2026 09:51:34 +0900 Subject: [PATCH] sd-device: seal object earlier Previously, the sd_device object was sealed after it was verified. However, the verifier device_verify() calls device_in_subsystem() which reads the uevent file if the object is not sealed. Hence, basic information such as MAJOR=/MINOR=/IFINDEX= and so on were updated by the uevent file, and the ones passed through netlink were simply discarded. Seal the device earlier, like we already do in device_clone_with_db(). This ensures all basic information passed through netlink is always honored. Fixes the following issue: $ journalctl --no-hostname --file TEST-17-UDEV.journal SEQNUM=2244 DEVNUM=259:1 Oct 12 04:44:22 systemd-udevd[404]: loop1p1: Device is queued (SEQNUM=2244, ACTION=remove) $ journalctl --no-hostname --file TEST-17-UDEV.journal SEQNUM=2244 DEVNUM=259:2 Oct 12 04:44:22 (udev-worker)[2593]: loop1p1: Processing device (SEQNUM=2244, ACTION=remove) Oct 12 04:44:22 (udev-worker)[2593]: Notify message sent to '@4814750286313953891': "INOTIFY_WATCH_REMOVE=1" Oct 12 04:44:22 (udev-worker)[2593]: loop1p1: Device processed (SEQNUM=2244, ACTION=remove) Oct 12 04:44:22 (udev-worker)[2593]: loop1p1: sd-device-monitor(worker): Passed 325 byte to netlink monitor. Oct 12 04:44:22 (udev-worker)[2593]: Notify message sent to '@4814750286313953891': "PROCESSED=1" Here, the main process of udevd receives the uevent with SEQNUM=2244 with MAJOR=259 and MINOR=1. However, when it is forwarded to the udev worker, MINOR= is changed to 2. Hence, the worker tries to read a wrong non-existent database file and cannot remove stale devlinks. Fixes a regression in ab1bd9daede454ac7cd5e5987bd345e7169894f8. (cherry picked from commit f58a2efc557a740891c5a56c82c971ae9a4e84c1) --- src/libsystemd/sd-device/device-private.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index a5638645c6..1c33d13d14 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -461,8 +461,6 @@ static int device_verify(sd_device *device) { "sd-device: Failed to set driver subsystem: %m"); } - device->sealed = true; - return 0; } @@ -478,6 +476,8 @@ int device_new_from_strv(sd_device **ret, char **strv) { if (r < 0) return r; + device_seal(device); + STRV_FOREACH(key, strv) { r = device_append(device, *key, &major, &minor); if (r < 0) @@ -512,6 +512,8 @@ int device_new_from_nulstr(sd_device **ret, char *nulstr, size_t len) { if (r < 0) return r; + device_seal(device); + for (size_t i = 0; i < len; ) { char *key; const char *end; @@ -661,7 +663,7 @@ int device_clone_with_db(sd_device *device, sd_device **ret) { return r; /* Seal device to prevent reading the uevent file, as the device may have been already removed. */ - dest->sealed = true; + device_seal(dest); /* Copy syspath, then also devname, sysname or sysnum can be obtained. */ r = device_set_syspath(dest, device->syspath, false);