Merge ~enr0n/ubuntu/+source/systemd:ubuntu-kinetic into ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-kinetic

Proposed by Nick Rosbrook
Status: Merged
Merged at revision: 6b2e008ecdea47dd8cc6fdadddf42a8199c51def
Proposed branch: ~enr0n/ubuntu/+source/systemd:ubuntu-kinetic
Merge into: ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-kinetic
Diff against target: 363 lines (+323/-0)
6 files modified
debian/changelog (+12/-0)
debian/patches/lp2002445/core-device-ignore-failed-uevents.patch (+43/-0)
debian/patches/lp2002445/sd-device-introduce-device_get_property_int.patch (+56/-0)
debian/patches/lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch (+45/-0)
debian/patches/lp2002445/udev-restore-syspath-and-properties-on-failure.patch (+163/-0)
debian/patches/series (+4/-0)
Reviewer Review Type Date Requested Status
Lukas Märdian Approve
Review via email: mp+439251@code.launchpad.net

Description of the change

The fix for LP: #2002445 is incomplete without these patches. In particular, udev needs to properly clean up modified device properties after failed renaming attempts. The full upstream PR is here: https://github.com/systemd/systemd/pull/25980.

Only the necessary commits from that PR are backported here.

PPA: https://launchpad.net/~enr0n/+archive/ubuntu/systemd-251
autopkgtest:

systemd 251.4-1ubuntu7.3~ppa1 (amd64) -- Fail: https://autopkgtest.ubuntu.com/results/autopkgtest-kinetic-enr0n-systemd-251/kinetic/amd64/s/systemd/20230318_031454_a5637@/log.gz
systemd 251.4-1ubuntu7.3~ppa1 (arm64) -- Fail: https://autopkgtest.ubuntu.com/results/autopkgtest-kinetic-enr0n-systemd-251/kinetic/arm64/s/systemd/20230317_232929_32459@/log.gz
systemd 251.4-1ubuntu7.3~ppa1 (armhf) -- Pass: https://autopkgtest.ubuntu.com/results/autopkgtest-kinetic-enr0n-systemd-251/kinetic/armhf/s/systemd/20230317_202546_eaf77@/log.gz
systemd 251.4-1ubuntu7.3~ppa1 (ppc64el) -- Fail: https://autopkgtest.ubuntu.com/results/autopkgtest-kinetic-enr0n-systemd-251/kinetic/ppc64el/s/systemd/20230317_203751_951c0@/log.gz

These failures are due to LP: #2009859, and the failing tests will not be considered regressions. The s390x test got lost or wasn't triggered correctly.

To post a comment you must log in.
Revision history for this message
Lukas Märdian (slyon) wrote (last edit ):

Thanks, refreshed/backported patches lgtm.

praise: I really like how you provide full context in the commit messages and merge-proposal (test-builds, autopkgtest logs + explanation). Kudos!

review: Approve
Revision history for this message
Lukas Märdian (slyon) wrote :

Sponsored as `debuild -S -d -v251.4-1ubuntu7.1`, to keep the previous 251.4-1ubuntu7.2 SRU changelog available.

https://launchpad.net/ubuntu/kinetic/+queue?queue_state=1&queue_text=systemd

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 2fe2841..4cb9182 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,15 @@
6+systemd (251.4-1ubuntu7.3) kinetic; urgency=medium
7+
8+ * udev: gracefully handle rename failures (LP: #2002445)
9+ Files:
10+ - debian/patches/lp2002445/core-device-ignore-failed-uevents.patch
11+ - debian/patches/lp2002445/sd-device-introduce-device_get_property_int.patch
12+ - debian/patches/lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch
13+ - debian/patches/lp2002445/udev-restore-syspath-and-properties-on-failure.patch
14+ https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=deb435fbb84fde1fd39da47231a7473fc2a412e8
15+
16+ -- Nick Rosbrook <nick.rosbrook@canonical.com> Mon, 20 Mar 2023 10:25:23 -0400
17+
18 systemd (251.4-1ubuntu7.2) kinetic; urgency=medium
19
20 * network/dhcp4: accept local subnet routes from DHCP (LP: #2004478)
21diff --git a/debian/patches/lp2002445/core-device-ignore-failed-uevents.patch b/debian/patches/lp2002445/core-device-ignore-failed-uevents.patch
22new file mode 100644
23index 0000000..2569151
24--- /dev/null
25+++ b/debian/patches/lp2002445/core-device-ignore-failed-uevents.patch
26@@ -0,0 +1,43 @@
27+From: Yu Watanabe <watanabe.yu+github@gmail.com>
28+Date: Mon, 9 Jan 2023 16:11:52 +0900
29+Subject: core/device: ignore failed uevents
30+
31+Origin: upstream, https://github.com/systemd/systemd/commit/e9336d6ac346df38d96c91ba0447b3c76ee6697b
32+Bug-Ubuntu: https://launchpad.net/bugs/2002445
33+
34+When udevd failed to process the device, SYSTEMD_ALIAS or any other
35+properties may contain invalid values. Let's refuse to handle the uevent.
36+---
37+ src/core/device.c | 19 +++++++++++++++++++
38+ 1 file changed, 19 insertions(+)
39+
40+diff --git a/src/core/device.c b/src/core/device.c
41+index fcde8a4..379cc8c 100644
42+--- a/src/core/device.c
43++++ b/src/core/device.c
44+@@ -976,6 +976,25 @@ static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *
45+ if (action == SD_DEVICE_MOVE)
46+ device_remove_old_on_move(m, dev);
47+
48++ /* When udevd failed to process the device, SYSTEMD_ALIAS or any other properties may contain invalid
49++ * values. Let's refuse to handle the uevent. */
50++ if (sd_device_get_property_value(dev, "UDEV_WORKER_FAILED", NULL) >= 0) {
51++ int v;
52++
53++ if (device_get_property_int(dev, "UDEV_WORKER_ERRNO", &v) >= 0)
54++ log_device_warning_errno(dev, v, "systemd-udevd failed to process the device, ignoring: %m");
55++ else if (device_get_property_int(dev, "UDEV_WORKER_EXIT_STATUS", &v) >= 0)
56++ log_device_warning(dev, "systemd-udevd failed to process the device with exit status %i, ignoring.", v);
57++ else if (device_get_property_int(dev, "UDEV_WORKER_SIGNAL", &v) >= 0) {
58++ const char *s;
59++ (void) sd_device_get_property_value(dev, "UDEV_WORKER_SIGNAL_NAME", &s);
60++ log_device_warning(dev, "systemd-udevd failed to process the device with signal %i(%s), ignoring.", v, strna(s));
61++ } else
62++ log_device_warning(dev, "systemd-udevd failed to process the device with unknown result, ignoring.");
63++
64++ return 0;
65++ }
66++
67+ /* A change event can signal that a device is becoming ready, in particular if the device is using
68+ * the SYSTEMD_READY logic in udev so we need to reach the else block of the following if, even for
69+ * change events */
70diff --git a/debian/patches/lp2002445/sd-device-introduce-device_get_property_int.patch b/debian/patches/lp2002445/sd-device-introduce-device_get_property_int.patch
71new file mode 100644
72index 0000000..26bb25f
73--- /dev/null
74+++ b/debian/patches/lp2002445/sd-device-introduce-device_get_property_int.patch
75@@ -0,0 +1,56 @@
76+From: Yu Watanabe <watanabe.yu+github@gmail.com>
77+Date: Mon, 9 Jan 2023 16:44:11 +0900
78+Subject: sd-device: introduce device_get_property_int()
79+
80+Origin: upstream, https://github.com/systemd/systemd/commit/eedfef0f0d2654fcde2a3b694e62518d688af827
81+Bug-Ubuntu: https://launchpad.net/bugs/2002445
82+
83+(modified to apply to v251.4)
84+---
85+ src/libsystemd/sd-device/device-private.h | 1 +
86+ src/libsystemd/sd-device/sd-device.c | 20 ++++++++++++++++++++
87+ 2 files changed, 21 insertions(+)
88+
89+diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h
90+index 9602f9e..4621033 100644
91+--- a/src/libsystemd/sd-device/device-private.h
92++++ b/src/libsystemd/sd-device/device-private.h
93+@@ -18,6 +18,7 @@ static inline int device_new_from_watch_handle(sd_device **ret, int wd) {
94+ }
95+
96+ int device_get_property_bool(sd_device *device, const char *key);
97++int device_get_property_int(sd_device *device, const char *key, int *ret);
98+ int device_get_device_id(sd_device *device, const char **ret);
99+ int device_get_devlink_priority(sd_device *device, int *ret);
100+ int device_get_watch_handle(sd_device *device);
101+diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
102+index 2fa78dc..5665022 100644
103+--- a/src/libsystemd/sd-device/sd-device.c
104++++ b/src/libsystemd/sd-device/sd-device.c
105+@@ -2026,6 +2026,26 @@ int device_get_property_bool(sd_device *device, const char *key) {
106+ return parse_boolean(value);
107+ }
108+
109++int device_get_property_int(sd_device *device, const char *key, int *ret) {
110++ const char *value;
111++ int r, v;
112++
113++ assert(device);
114++ assert(key);
115++
116++ r = sd_device_get_property_value(device, key, &value);
117++ if (r < 0)
118++ return r;
119++
120++ r = safe_atoi(value, &v);
121++ if (r < 0)
122++ return r;
123++
124++ if (ret)
125++ *ret = v;
126++ return 0;
127++}
128++
129+ _public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) {
130+ const char *s;
131+ sd_id128_t id;
132diff --git a/debian/patches/lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch b/debian/patches/lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch
133new file mode 100644
134index 0000000..bc4a098
135--- /dev/null
136+++ b/debian/patches/lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch
137@@ -0,0 +1,45 @@
138+From: Yu Watanabe <watanabe.yu+github@gmail.com>
139+Date: Mon, 9 Jan 2023 14:00:09 +0900
140+Subject: sd-device: make device_set_syspath() clear sysname and sysnum
141+
142+Origin: upstream, https://github.com/systemd/systemd/commit/9a26098e90116fdb5fcffa03485b375ee0c82b6a
143+Bug-Ubuntu: https://launchpad.net/bugs/2002445
144+
145+Otherwise, when a new syspath is assigned to the sd-device object,
146+sd_device_get_sysname() or _sysnum() will provide an outdated device
147+name or number.
148+---
149+ src/libsystemd/sd-device/device-private.c | 4 ----
150+ src/libsystemd/sd-device/sd-device.c | 4 ++++
151+ 2 files changed, 4 insertions(+), 4 deletions(-)
152+
153+diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
154+index a453899..ddca336 100644
155+--- a/src/libsystemd/sd-device/device-private.c
156++++ b/src/libsystemd/sd-device/device-private.c
157+@@ -784,10 +784,6 @@ int device_rename(sd_device *device, const char *name) {
158+ if (r < 0)
159+ return r;
160+
161+- /* Here, only clear the sysname and sysnum. They will be set when requested. */
162+- device->sysnum = NULL;
163+- device->sysname = mfree(device->sysname);
164+-
165+ r = sd_device_get_property_value(device, "INTERFACE", &interface);
166+ if (r == -ENOENT)
167+ return 0;
168+diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
169+index 62531b9..2fa78dc 100644
170+--- a/src/libsystemd/sd-device/sd-device.c
171++++ b/src/libsystemd/sd-device/sd-device.c
172+@@ -247,6 +247,10 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
173+
174+ free_and_replace(device->syspath, syspath);
175+ device->devpath = devpath;
176++
177++ /* Unset sysname and sysnum, they will be assigned when requested. */
178++ device->sysnum = NULL;
179++ device->sysname = mfree(device->sysname);
180+ return 0;
181+ }
182+
183diff --git a/debian/patches/lp2002445/udev-restore-syspath-and-properties-on-failure.patch b/debian/patches/lp2002445/udev-restore-syspath-and-properties-on-failure.patch
184new file mode 100644
185index 0000000..543c1ec
186--- /dev/null
187+++ b/debian/patches/lp2002445/udev-restore-syspath-and-properties-on-failure.patch
188@@ -0,0 +1,163 @@
189+From: Yu Watanabe <watanabe.yu+github@gmail.com>
190+Date: Mon, 9 Jan 2023 14:58:58 +0900
191+Subject: udev: restore syspath and properties on failure
192+
193+Origin: upstream, https://github.com/systemd/systemd/commit/210033847c340c43dd6835520f21f8b23ba29579
194+Bug-Ubuntu: https://launchpad.net/bugs/2002445
195+
196+Otherwise, invalid sysname or properties may be broadcast to udev
197+listeners.
198+
199+(modified to apply to v251.4)
200+---
201+ src/udev/udev-event.c | 94 +++++++++++++++++++++++++++++++++++----------------
202+ 1 file changed, 65 insertions(+), 29 deletions(-)
203+
204+diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
205+index 681aa87..8b8bb4d 100644
206+--- a/src/udev/udev-event.c
207++++ b/src/udev/udev-event.c
208+@@ -12,6 +12,7 @@
209+ #include "sd-event.h"
210+
211+ #include "alloc-util.h"
212++#include "device-internal.h"
213+ #include "device-private.h"
214+ #include "device-util.h"
215+ #include "fd-util.h"
216+@@ -869,7 +870,8 @@ int udev_event_spawn(
217+ }
218+
219+ static int rename_netif(UdevEvent *event) {
220+- const char *oldname;
221++ _cleanup_free_ char *old_syspath = NULL, *old_sysname = NULL;
222++ const char *s;
223+ sd_device *dev;
224+ int ifindex, r;
225+
226+@@ -880,15 +882,6 @@ static int rename_netif(UdevEvent *event) {
227+
228+ dev = ASSERT_PTR(event->dev);
229+
230+- /* Read sysname from cloned sd-device object, otherwise use-after-free is triggered, as the
231+- * main object will be renamed and dev->sysname will be freed in device_rename(). */
232+- r = sd_device_get_sysname(event->dev_db_clone, &oldname);
233+- if (r < 0)
234+- return log_device_error_errno(dev, r, "Failed to get sysname: %m");
235+-
236+- if (streq(event->name, oldname))
237+- return 0; /* The interface name is already requested name. */
238+-
239+ if (!device_for_action(dev, SD_DEVICE_ADD))
240+ return 0; /* Rename the interface only when it is added. */
241+
242+@@ -896,7 +889,7 @@ static int rename_netif(UdevEvent *event) {
243+ if (r == -ENOENT)
244+ return 0; /* Device is not a network interface. */
245+ if (r < 0)
246+- return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
247++ return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
248+
249+ if (naming_scheme_has(NAMING_REPLACE_STRICTLY) &&
250+ !ifname_valid(event->name)) {
251+@@ -904,39 +897,82 @@ static int rename_netif(UdevEvent *event) {
252+ return 0;
253+ }
254+
255+- /* Set ID_RENAMING boolean property here, and drop it in the corresponding move uevent later. */
256+- r = device_add_property(dev, "ID_RENAMING", "1");
257++ r = sd_device_get_sysname(dev, &s);
258+ if (r < 0)
259+- return log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
260++ return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
261+
262+- r = device_rename(dev, event->name);
263++ if (streq(event->name, s))
264++ return 0; /* The interface name is already requested name. */
265++
266++ old_sysname = strdup(s);
267++ if (!old_sysname)
268++ return -ENOMEM;
269++
270++ r = sd_device_get_syspath(dev, &s);
271+ if (r < 0)
272+- return log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
273++ return log_device_warning_errno(dev, r, "Failed to get syspath: %m");
274++
275++ old_syspath = strdup(s);
276++ if (!old_syspath)
277++ return -ENOMEM;
278++
279++ r = device_rename(dev, event->name);
280++ if (r < 0) {
281++ log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
282++ goto revert;
283++ }
284++
285++ /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
286++ r = device_add_property(dev, "ID_RENAMING", "1");
287++ if (r < 0) {
288++ log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
289++ goto revert;
290++ }
291+
292+ /* Also set ID_RENAMING boolean property to cloned sd_device object and save it to database
293+ * before calling rtnl_set_link_name(). Otherwise, clients (e.g., systemd-networkd) may receive
294+ * RTM_NEWLINK netlink message before the database is updated. */
295+ r = device_add_property(event->dev_db_clone, "ID_RENAMING", "1");
296+- if (r < 0)
297+- return log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
298++ if (r < 0) {
299++ log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
300++ goto revert;
301++ }
302+
303+ r = device_update_db(event->dev_db_clone);
304+- if (r < 0)
305+- return log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
306++ if (r < 0) {
307++ log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
308++ goto revert;
309++ }
310+
311+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
312+- if (r == -EBUSY) {
313+- log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
314+- oldname, event->name);
315+- return 0;
316++ if (r < 0) {
317++ if (r == -EBUSY) {
318++ log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
319++ old_sysname, event->name);
320++ r = 0;
321++ } else
322++ log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
323++ ifindex, old_sysname, event->name);
324++ goto revert;
325+ }
326+- if (r < 0)
327+- return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
328+- ifindex, oldname, event->name);
329+-
330+- log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, oldname, event->name);
331+
332++ log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, old_sysname, event->name);
333+ return 1;
334++
335++revert:
336++ /* Restore 'dev_db_clone' */
337++ (void) device_add_property(event->dev_db_clone, "ID_RENAMING", NULL);
338++ (void) device_update_db(event->dev_db_clone);
339++
340++ /* Restore 'dev' */
341++ (void) device_set_syspath(dev, old_syspath, /* verify = */ false);
342++ if (sd_device_get_property_value(dev, "INTERFACE_OLD", &s) >= 0) {
343++ (void) device_add_property_internal(dev, "INTERFACE", s);
344++ (void) device_add_property_internal(dev, "INTERFACE_OLD", NULL);
345++ }
346++ (void) device_add_property(dev, "ID_RENAMING", NULL);
347++
348++ return r;
349+ }
350+
351+ static int update_devnode(UdevEvent *event) {
352diff --git a/debian/patches/series b/debian/patches/series
353index 24359ad..3727627 100644
354--- a/debian/patches/series
355+++ b/debian/patches/series
356@@ -61,3 +61,7 @@ lp2002445/sd-netlink-do-not-swap-old-name-and-alternative-name.patch
357 lp2002445/sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch
358 lp2002445/udev-attempt-device-rename-even-if-interface-is-up.patch
359 lp2002445/sd-netlink-add-a-test-for-rtnl_set_link_name.patch
360+lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch
361+lp2002445/udev-restore-syspath-and-properties-on-failure.patch
362+lp2002445/sd-device-introduce-device_get_property_int.patch
363+lp2002445/core-device-ignore-failed-uevents.patch

Subscribers

People subscribed via source and target branches