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

Proposed by Nick Rosbrook
Status: Merged
Merged at revision: 0e602e907209769858e2e7fb4cf5cacdd93fb742
Proposed branch: ~enr0n/ubuntu/+source/systemd:ubuntu-lunar
Merge into: ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-lunar
Diff against target: 360 lines (+320/-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 (+55/-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 (+161/-0)
debian/patches/series (+4/-0)
Reviewer Review Type Date Requested Status
Lukas Märdian Approve
Review via email: mp+439250@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
autopkgtest:

systemd 252.5-2ubuntu3~ppa3 (amd64) -- Pass: https://autopkgtest.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/amd64/s/systemd/20230317_234655_d734e@/log.gz
systemd 252.5-2ubuntu3~ppa3 (arm64) -- Pass: https://autopkgtest.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/arm64/s/systemd/20230317_234410_8d883@/log.gz
systemd 252.5-2ubuntu3~ppa3 (armhf) -- Pass: https://autopkgtest.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/armhf/s/systemd/20230317_202006_6acc4@/log.gz
systemd 252.5-2ubuntu3~ppa3 (ppc64el) -- Pass: https://autopkgtest.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/ppc64el/s/systemd/20230317_214145_957ed@/log.gz
systemd 252.5-2ubuntu3~ppa3 (s390x) -- Fail: https://autopkgtest.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/s390x/s/systemd/20230317_221114_4f4cf@/log.gz

The s390x appears to be a test bed failure. All tests up to that point had passed.

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

Thanks, lgtm. Patches are matching the upstream commits.

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

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 bc515ad..cb44d04 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,15 @@
6+systemd (252.5-2ubuntu3) lunar; 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=79536dbb165dbcc402629684e0911693626df5b1
15+
16+ -- Nick Rosbrook <nick.rosbrook@canonical.com> Mon, 20 Mar 2023 10:17:24 -0400
17+
18 systemd (252.5-2ubuntu2) lunar; 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..2044779
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 6e07f27..d3a052d 100644
42+--- a/src/core/device.c
43++++ b/src/core/device.c
44+@@ -1137,6 +1137,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..439f257
73--- /dev/null
74+++ b/debian/patches/lp2002445/sd-device-introduce-device_get_property_int.patch
75@@ -0,0 +1,55 @@
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+---
84+ src/libsystemd/sd-device/device-private.h | 1 +
85+ src/libsystemd/sd-device/sd-device.c | 20 ++++++++++++++++++++
86+ 2 files changed, 21 insertions(+)
87+
88+diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h
89+index a59f130..f46abee 100644
90+--- a/src/libsystemd/sd-device/device-private.h
91++++ b/src/libsystemd/sd-device/device-private.h
92+@@ -18,6 +18,7 @@ int device_new_from_strv(sd_device **ret, char **strv);
93+ int device_opendir(sd_device *device, const char *subdir, DIR **ret);
94+
95+ int device_get_property_bool(sd_device *device, const char *key);
96++int device_get_property_int(sd_device *device, const char *key, int *ret);
97+ int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value);
98+ int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value);
99+ int device_get_sysattr_bool(sd_device *device, const char *sysattr);
100+diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
101+index d35726d..4aecf7c 100644
102+--- a/src/libsystemd/sd-device/sd-device.c
103++++ b/src/libsystemd/sd-device/sd-device.c
104+@@ -2186,6 +2186,26 @@ int device_get_property_bool(sd_device *device, const char *key) {
105+ return parse_boolean(value);
106+ }
107+
108++int device_get_property_int(sd_device *device, const char *key, int *ret) {
109++ const char *value;
110++ int r, v;
111++
112++ assert(device);
113++ assert(key);
114++
115++ r = sd_device_get_property_value(device, key, &value);
116++ if (r < 0)
117++ return r;
118++
119++ r = safe_atoi(value, &v);
120++ if (r < 0)
121++ return r;
122++
123++ if (ret)
124++ *ret = v;
125++ return 0;
126++}
127++
128+ _public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) {
129+ const char *s;
130+ sd_id128_t id;
131diff --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
132new file mode 100644
133index 0000000..9621622
134--- /dev/null
135+++ b/debian/patches/lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch
136@@ -0,0 +1,45 @@
137+From: Yu Watanabe <watanabe.yu+github@gmail.com>
138+Date: Mon, 9 Jan 2023 14:00:09 +0900
139+Subject: sd-device: make device_set_syspath() clear sysname and sysnum
140+
141+Origin: upstream, https://github.com/systemd/systemd/commit/9a26098e90116fdb5fcffa03485b375ee0c82b6a
142+Bug-Ubuntu: https://launchpad.net/bugs/2002445
143+
144+Otherwise, when a new syspath is assigned to the sd-device object,
145+sd_device_get_sysname() or _sysnum() will provide an outdated device
146+name or number.
147+---
148+ src/libsystemd/sd-device/device-private.c | 4 ----
149+ src/libsystemd/sd-device/sd-device.c | 4 ++++
150+ 2 files changed, 4 insertions(+), 4 deletions(-)
151+
152+diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
153+index bc7a838..2c1d922 100644
154+--- a/src/libsystemd/sd-device/device-private.c
155++++ b/src/libsystemd/sd-device/device-private.c
156+@@ -646,10 +646,6 @@ int device_rename(sd_device *device, const char *name) {
157+ if (r < 0)
158+ return r;
159+
160+- /* Here, only clear the sysname and sysnum. They will be set when requested. */
161+- device->sysnum = NULL;
162+- device->sysname = mfree(device->sysname);
163+-
164+ r = sd_device_get_property_value(device, "INTERFACE", &interface);
165+ if (r == -ENOENT)
166+ return 0;
167+diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
168+index ff5d065..d35726d 100644
169+--- a/src/libsystemd/sd-device/sd-device.c
170++++ b/src/libsystemd/sd-device/sd-device.c
171+@@ -250,6 +250,10 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
172+
173+ free_and_replace(device->syspath, syspath);
174+ device->devpath = devpath;
175++
176++ /* Unset sysname and sysnum, they will be assigned when requested. */
177++ device->sysnum = NULL;
178++ device->sysname = mfree(device->sysname);
179+ return 0;
180+ }
181+
182diff --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
183new file mode 100644
184index 0000000..ab717da
185--- /dev/null
186+++ b/debian/patches/lp2002445/udev-restore-syspath-and-properties-on-failure.patch
187@@ -0,0 +1,161 @@
188+From: Yu Watanabe <watanabe.yu+github@gmail.com>
189+Date: Mon, 9 Jan 2023 14:58:58 +0900
190+Subject: udev: restore syspath and properties on failure
191+
192+Origin: upstream, https://github.com/systemd/systemd/commit/210033847c340c43dd6835520f21f8b23ba29579
193+Bug-Ubuntu: https://launchpad.net/bugs/2002445
194+
195+Otherwise, invalid sysname or properties may be broadcast to udev
196+listeners.
197+---
198+ src/udev/udev-event.c | 94 +++++++++++++++++++++++++++++++++++----------------
199+ 1 file changed, 65 insertions(+), 29 deletions(-)
200+
201+diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
202+index 08d69cf..f5a10d9 100644
203+--- a/src/udev/udev-event.c
204++++ b/src/udev/udev-event.c
205+@@ -12,6 +12,7 @@
206+ #include "sd-event.h"
207+
208+ #include "alloc-util.h"
209++#include "device-internal.h"
210+ #include "device-private.h"
211+ #include "device-util.h"
212+ #include "fd-util.h"
213+@@ -860,7 +861,8 @@ int udev_event_spawn(
214+ }
215+
216+ static int rename_netif(UdevEvent *event) {
217+- const char *oldname;
218++ _cleanup_free_ char *old_syspath = NULL, *old_sysname = NULL;
219++ const char *s;
220+ sd_device *dev;
221+ int ifindex, r;
222+
223+@@ -871,15 +873,6 @@ static int rename_netif(UdevEvent *event) {
224+
225+ dev = ASSERT_PTR(event->dev);
226+
227+- /* Read sysname from cloned sd-device object, otherwise use-after-free is triggered, as the
228+- * main object will be renamed and dev->sysname will be freed in device_rename(). */
229+- r = sd_device_get_sysname(event->dev_db_clone, &oldname);
230+- if (r < 0)
231+- return log_device_error_errno(dev, r, "Failed to get sysname: %m");
232+-
233+- if (streq(event->name, oldname))
234+- return 0; /* The interface name is already requested name. */
235+-
236+ if (!device_for_action(dev, SD_DEVICE_ADD))
237+ return 0; /* Rename the interface only when it is added. */
238+
239+@@ -887,7 +880,7 @@ static int rename_netif(UdevEvent *event) {
240+ if (r == -ENOENT)
241+ return 0; /* Device is not a network interface. */
242+ if (r < 0)
243+- return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
244++ return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
245+
246+ if (naming_scheme_has(NAMING_REPLACE_STRICTLY) &&
247+ !ifname_valid(event->name)) {
248+@@ -895,39 +888,82 @@ static int rename_netif(UdevEvent *event) {
249+ return 0;
250+ }
251+
252+- /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
253+- r = device_add_property(dev, "ID_RENAMING", "1");
254++ r = sd_device_get_sysname(dev, &s);
255+ if (r < 0)
256+- return log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
257++ return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
258+
259+- r = device_rename(dev, event->name);
260++ if (streq(event->name, s))
261++ return 0; /* The interface name is already requested name. */
262++
263++ old_sysname = strdup(s);
264++ if (!old_sysname)
265++ return -ENOMEM;
266++
267++ r = sd_device_get_syspath(dev, &s);
268+ if (r < 0)
269+- return log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
270++ return log_device_warning_errno(dev, r, "Failed to get syspath: %m");
271++
272++ old_syspath = strdup(s);
273++ if (!old_syspath)
274++ return -ENOMEM;
275++
276++ r = device_rename(dev, event->name);
277++ if (r < 0) {
278++ log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
279++ goto revert;
280++ }
281++
282++ /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
283++ r = device_add_property(dev, "ID_RENAMING", "1");
284++ if (r < 0) {
285++ log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
286++ goto revert;
287++ }
288+
289+ /* Also set ID_RENAMING boolean property to cloned sd_device object and save it to database
290+ * before calling rtnl_set_link_name(). Otherwise, clients (e.g., systemd-networkd) may receive
291+ * RTM_NEWLINK netlink message before the database is updated. */
292+ r = device_add_property(event->dev_db_clone, "ID_RENAMING", "1");
293+- if (r < 0)
294+- return log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
295++ if (r < 0) {
296++ log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
297++ goto revert;
298++ }
299+
300+ r = device_update_db(event->dev_db_clone);
301+- if (r < 0)
302+- return log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
303++ if (r < 0) {
304++ log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
305++ goto revert;
306++ }
307+
308+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
309+- if (r == -EBUSY) {
310+- log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
311+- oldname, event->name);
312+- return 0;
313++ if (r < 0) {
314++ if (r == -EBUSY) {
315++ log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
316++ old_sysname, event->name);
317++ r = 0;
318++ } else
319++ log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
320++ ifindex, old_sysname, event->name);
321++ goto revert;
322+ }
323+- if (r < 0)
324+- return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
325+- ifindex, oldname, event->name);
326+-
327+- log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, oldname, event->name);
328+
329++ log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, old_sysname, event->name);
330+ return 1;
331++
332++revert:
333++ /* Restore 'dev_db_clone' */
334++ (void) device_add_property(event->dev_db_clone, "ID_RENAMING", NULL);
335++ (void) device_update_db(event->dev_db_clone);
336++
337++ /* Restore 'dev' */
338++ (void) device_set_syspath(dev, old_syspath, /* verify = */ false);
339++ if (sd_device_get_property_value(dev, "INTERFACE_OLD", &s) >= 0) {
340++ (void) device_add_property_internal(dev, "INTERFACE", s);
341++ (void) device_add_property_internal(dev, "INTERFACE_OLD", NULL);
342++ }
343++ (void) device_add_property(dev, "ID_RENAMING", NULL);
344++
345++ return r;
346+ }
347+
348+ static int update_devnode(UdevEvent *event) {
349diff --git a/debian/patches/series b/debian/patches/series
350index 749ad23..ac0e72b 100644
351--- a/debian/patches/series
352+++ b/debian/patches/series
353@@ -53,3 +53,7 @@ lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch
354 Deny-list-TEST-74-AUX-UTILS-on-s390x.patch
355 lp2004478-network-dhcp4-accept-local-subnet-routes-from-DHCP.patch
356 sd-netlink-skip-test_rtnl_set_link_name-when-altnames-are.patch
357+lp2002445/sd-device-make-device_set_syspath-clear-sysname-and-sysnu.patch
358+lp2002445/udev-restore-syspath-and-properties-on-failure.patch
359+lp2002445/sd-device-introduce-device_get_property_int.patch
360+lp2002445/core-device-ignore-failed-uevents.patch

Subscribers

People subscribed via source and target branches