From 4fa3df0252f35162fe039ccf598bb72bf686a8d2 Mon Sep 17 00:00:00 2001 From: hongjinghao Date: Fri, 16 Jun 2023 10:25:11 +0800 Subject: [PATCH] sync community patches --- ...-serialize-deserialize-device-syspat.patch | 63 ++++++++++ ...evice_coldplug-don-t-set-DEVICE_DEAD.patch | 43 +++++++ ...ot-downgrade-device-state-if-it-is-a.patch | 36 ++++++ ...re-device-drop-unnecessary-condition.patch | 28 +++++ ...re-DEVICE_FOUND_UDEV-bit-on-switchin.patch | 117 ++++++++++++++++++ backport-core-device-update-comment.patch | 65 ++++++++++ ...ify-device-syspath-on-switching-root.patch | 42 +++++++ ...ANAGER_IS_SWITCHING_ROOT-helper-func.patch | 91 ++++++++++++++ ...-Type-dbus-service-enqueuing-if-dbus.patch | 91 ++++++++++++++ ...us-activation-if-dbus-is-not-running.patch | 43 +++++++ ...onor_device_enumeration-with-MANAGER.patch | 113 +++++++++++++++++ backport-core-timer-fix-memleak.patch | 61 +++++++++ ...e-timer-fix-potential-use-after-free.patch | 26 ++++ backport-core-unit-fix-use-after-free.patch | 30 +++++ ...low-transient-units-to-have-drop-ins.patch | 90 ++++++++++++++ ...-boolean-expression-in-unit_is_prist.patch | 40 ++++++ ...t-always-initialize-sd_event.perturb.patch | 59 +++++++++ backport-sd-event-fix-error-handling.patch | 31 +++++ ...py_safe-as-the-buffer-size-may-be-ze.patch | 27 ++++ ...avoid-crashing-on-config-without-a-v.patch | 31 +++++ backport-timedatectl-fix-a-memory-leak.patch | 46 +++++++ ...-udev-cdrom_id-check-last-track-info.patch | 31 +++++ systemd.spec | 27 +++- 23 files changed, 1230 insertions(+), 1 deletion(-) create mode 100644 backport-core-device-also-serialize-deserialize-device-syspat.patch create mode 100644 backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch create mode 100644 backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch create mode 100644 backport-core-device-drop-unnecessary-condition.patch create mode 100644 backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch create mode 100644 backport-core-device-update-comment.patch create mode 100644 backport-core-device-verify-device-syspath-on-switching-root.patch create mode 100644 backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch create mode 100644 backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch create mode 100644 backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch create mode 100644 backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch create mode 100644 backport-core-timer-fix-memleak.patch create mode 100644 backport-core-timer-fix-potential-use-after-free.patch create mode 100644 backport-core-unit-fix-use-after-free.patch create mode 100644 backport-manager-allow-transient-units-to-have-drop-ins.patch create mode 100644 backport-manager-reformat-boolean-expression-in-unit_is_prist.patch create mode 100644 backport-sd-event-always-initialize-sd_event.perturb.patch create mode 100644 backport-sd-event-fix-error-handling.patch create mode 100644 backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch create mode 100644 backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch create mode 100644 backport-timedatectl-fix-a-memory-leak.patch create mode 100644 backport-udev-cdrom_id-check-last-track-info.patch diff --git a/backport-core-device-also-serialize-deserialize-device-syspat.patch b/backport-core-device-also-serialize-deserialize-device-syspat.patch new file mode 100644 index 00000000..08d94f11 --- /dev/null +++ b/backport-core-device-also-serialize-deserialize-device-syspat.patch @@ -0,0 +1,63 @@ +From 1ea74fca3a3c737f3901bc10d879b7830b3528bf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 25 Oct 2022 21:41:17 +0900 +Subject: [PATCH] core/device: also serialize/deserialize device syspath + +The field will be used in later commits. +--- + src/core/device.c | 11 ++++++++++- + src/core/device.h | 2 +- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index fe66367..16c6132 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -110,6 +110,7 @@ static void device_done(Unit *u) { + assert(d); + + device_unset_sysfs(d); ++ d->deserialized_sysfs = mfree(d->deserialized_sysfs); + d->wants_property = strv_free(d->wants_property); + } + +@@ -293,6 +294,9 @@ static int device_serialize(Unit *u, FILE *f, FDSet *fds) { + assert(f); + assert(fds); + ++ if (d->sysfs) ++ (void) serialize_item(f, "sysfs", d->sysfs); ++ + (void) serialize_item(f, "state", device_state_to_string(d->state)); + + if (device_found_to_string_many(d->found, &s) >= 0) +@@ -310,7 +314,12 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value, + assert(value); + assert(fds); + +- if (streq(key, "state")) { ++ if (streq(key, "sysfs")) { ++ if (!d->deserialized_sysfs) { ++ d->deserialized_sysfs = strdup(value); ++ } ++ ++ } else if (streq(key, "state")) { + DeviceState state; + + state = device_state_from_string(value); +diff --git a/src/core/device.h b/src/core/device.h +index 3062be7..1164117 100644 +--- a/src/core/device.h ++++ b/src/core/device.h +@@ -20,7 +20,7 @@ typedef enum DeviceFound { + struct Device { + Unit meta; + +- char *sysfs; ++ char *sysfs, *deserialized_sysfs; + + /* In order to be able to distinguish dependencies on different device nodes we might end up creating multiple + * devices for the same sysfs path. We chain them up here. */ +-- +2.33.0 + diff --git a/backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch b/backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch new file mode 100644 index 00000000..2f3964ce --- /dev/null +++ b/backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch @@ -0,0 +1,43 @@ +From cf1ac0cfe44997747b0f857a1d0b67cea1298272 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 25 May 2022 12:01:00 +0200 +Subject: [PATCH] core/device: device_coldplug(): don't set DEVICE_DEAD + +dm-crypt device units generated by systemd-cryptsetup-generator +habe BindsTo= dependencies on their backend devices. The dm-crypt +devices have the db_persist flag set, and thus survive the udev db +cleanup while switching root. But backend devices usually don't survive. +These devices are neither mounted nor used for swap, thus they will +seen as DEVICE_NOT_FOUND after switching root. + +The BindsTo dependency will cause systemd to schedule a stop +job for the dm-crypt device, breaking boot: + +[ 68.929457] krypton systemd[1]: systemd-cryptsetup@cr_root.service: Unit is stopped because bound to inactive unit dev-disk-by\x2duuid-3bf91f73\x2d1ee8\x2d4cfc\x2d9048\x2d93ba349b786d.device. +[ 68.945660] krypton systemd[1]: systemd-cryptsetup@cr_root.service: Trying to enqueue job systemd-cryptsetup@cr_root.service/stop/replace +[ 69.473459] krypton systemd[1]: systemd-cryptsetup@cr_root.service: Installed new job systemd-cryptsetup@cr_root.service/stop as 343 + +Avoid this by not setting the state of the backend devices to +DEVICE_DEAD. + +Fixes the LUKS setup issue reported in #23429. +--- + src/core/device.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 4c261ec554..8728630523 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -205,8 +205,6 @@ static int device_coldplug(Unit *u) { + found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ + if (state == DEVICE_PLUGGED) + state = DEVICE_TENTATIVE; /* downgrade state */ +- if (found == DEVICE_NOT_FOUND) +- state = DEVICE_DEAD; /* If nobody sees the device, downgrade more */ + } + + if (d->found == found && d->state == state) +-- +2.33.0 + diff --git a/backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch b/backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch new file mode 100644 index 00000000..76075801 --- /dev/null +++ b/backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch @@ -0,0 +1,36 @@ +From 4fc69e8a0949c2537019466f839d9b7aee5628c9 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 20 May 2022 10:25:12 +0200 +Subject: [PATCH] core/device: do not downgrade device state if it is already + enumerated + +On switching root, a device may have a persistent databse. In that case, +Device.enumerated_found may have DEVICE_FOUND_UDEV flag, and it is not +necessary to downgrade the Device.deserialized_found and +Device.deserialized_state. Otherwise, the state of the device unit may +be changed plugged -> dead -> plugged, if the device has not been mounted. + +Fixes #23429. + +[mwilck: cherry-picked from #23437] +--- + src/core/device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 8728630523..fcde8a420e 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -201,7 +201,8 @@ static int device_coldplug(Unit *u) { + * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by + * device_catchup() or uevents. */ + +- if (!m->honor_device_enumeration && !MANAGER_IS_USER(m)) { ++ if (!m->honor_device_enumeration && !MANAGER_IS_USER(m) && ++ !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) { + found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ + if (state == DEVICE_PLUGGED) + state = DEVICE_TENTATIVE; /* downgrade state */ +-- +2.33.0 + diff --git a/backport-core-device-drop-unnecessary-condition.patch b/backport-core-device-drop-unnecessary-condition.patch new file mode 100644 index 00000000..1e8b7bf8 --- /dev/null +++ b/backport-core-device-drop-unnecessary-condition.patch @@ -0,0 +1,28 @@ +From f33bc87989a87475ed41bc9cd715c4cbb18ee389 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 1 May 2022 21:42:43 +0900 +Subject: [PATCH] core/device: drop unnecessary condition + +--- + src/core/device.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 44425cda3c..934676287e 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -179,10 +179,7 @@ static void device_catchup(Unit *u) { + + assert(d); + +- /* Second, let's update the state with the enumerated state if it's different */ +- if (d->enumerated_found == d->found) +- return; +- ++ /* Second, let's update the state with the enumerated state */ + device_update_found_one(d, d->enumerated_found, DEVICE_FOUND_MASK); + } + +-- +2.33.0 + diff --git a/backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch b/backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch new file mode 100644 index 00000000..f2b40962 --- /dev/null +++ b/backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch @@ -0,0 +1,117 @@ +From 75d7b5989f99125e52d5c0e5656fa1cd0fae2405 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 29 Apr 2022 20:29:11 +0900 +Subject: [PATCH] core/device: ignore DEVICE_FOUND_UDEV bit on switching root + +The issue #12953 is caused by the following: +On switching root, +- deserialized_found == DEVICE_FOUND_UDEV | DEVICE_FOUND_MOUNT, +- deserialized_state == DEVICE_PLUGGED, +- enumerated_found == DEVICE_FOUND_MOUNT, +On switching root, most devices are not found by the enumeration process. +Hence, the device state is set to plugged by device_coldplug(), and then +changed to the dead state in device_catchup(). So the corresponding +mount point is unmounted. Later when the device is processed by udevd, it +will be changed to plugged state again. + +The issue #23208 is caused by the fact that generated udev database in +initramfs and the main system are often different. + +So, the two issues have the same root; we should not honor +DEVICE_FOUND_UDEV bit in the deserialized_found on switching root. + +This partially reverts c6e892bc0eebe1d42c282bd2d8bae149fbeba85f. + +Fixes #12953 and #23208. +Replaces #23215. + +Co-authored-by: Martin Wilck +--- + src/core/device.c | 59 +++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 49 insertions(+), 10 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 934676287e..1a4563a3d9 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -163,14 +163,57 @@ static int device_coldplug(Unit *u) { + assert(d->state == DEVICE_DEAD); + + /* First, let's put the deserialized state and found mask into effect, if we have it. */ ++ if (d->deserialized_state < 0) ++ return 0; ++ ++ Manager *m = u->manager; ++ DeviceFound found = d->deserialized_found; ++ DeviceState state = d->deserialized_state; ++ ++ /* On initial boot, switch-root, reload, reexecute, the following happen: ++ * 1. MANAGER_IS_RUNNING() == false ++ * 2. enumerate devices: manager_enumerate() -> device_enumerate() ++ * Device.enumerated_found is set. ++ * 3. deserialize devices: manager_deserialize() -> device_deserialize() ++ * Device.deserialize_state and Device.deserialized_found are set. ++ * 4. coldplug devices: manager_coldplug() -> device_coldplug() ++ * deserialized properties are copied to the main properties. ++ * 5. MANAGER_IS_RUNNING() == true: manager_ready() ++ * 6. catchup devices: manager_catchup() -> device_catchup() ++ * Device.enumerated_found is applied to Device.found, and state is updated based on that. ++ * ++ * Notes: ++ * - On initial boot, no udev database exists. Hence, no devices are enumerated in the step 2. ++ * Also, there is no deserialized device. Device units are (a) generated based on dependencies of ++ * other units, or (b) generated when uevents are received. ++ * ++ * - On switch-root, the udev databse may be cleared, except for devices with sticky bit, i.e. ++ * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general, ++ * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be ++ * ignored, as udev rules in initramfs and the main system are often different. If the deserialized ++ * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE (or DEVICE_DEAD if nobody ++ * sees the device). Unlike the other starting mode, Manager.honor_device_enumeration == false ++ * (maybe, it is better to rename the flag) when device_coldplug() and device_catchup() are called. ++ * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd ++ * will (re-)process all devices, and the Device.found and Device.state will be adjusted. ++ * ++ * - On reload or reexecute, we can trust enumerated_found, deserialized_found, and deserialized_state. ++ * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by ++ * device_catchup() or uevents. */ ++ ++ if (!m->honor_device_enumeration && !MANAGER_IS_USER(m)) { ++ found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ ++ if (state == DEVICE_PLUGGED) ++ state = DEVICE_TENTATIVE; /* downgrade state */ ++ if (found == DEVICE_NOT_FOUND) ++ state = DEVICE_DEAD; /* If nobody sees the device, downgrade more */ ++ } + +- if (d->deserialized_state < 0 || +- (d->deserialized_state == d->state && +- d->deserialized_found == d->found)) ++ if (d->found == found && d->state == state) + return 0; + +- d->found = d->deserialized_found; +- device_set_state(d, d->deserialized_state); ++ d->found = found; ++ device_set_state(d, state); + return 0; + } + +@@ -644,13 +687,9 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no + } + + static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) { +- Manager *m; +- + assert(d); + +- m = UNIT(d)->manager; +- +- if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) { ++ if (MANAGER_IS_RUNNING(UNIT(d)->manager)) { + DeviceFound n, previous; + + /* When we are already running, then apply the new mask right-away, and trigger state changes +-- +2.33.0 + diff --git a/backport-core-device-update-comment.patch b/backport-core-device-update-comment.patch new file mode 100644 index 00000000..52a11310 --- /dev/null +++ b/backport-core-device-update-comment.patch @@ -0,0 +1,65 @@ +From 54a4d71509c0f3401aa576346754a0781795214a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 25 Oct 2022 21:40:21 +0900 +Subject: [PATCH] core/device: update comment + +--- + src/core/device.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 99666ab..fe66367 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -168,7 +168,7 @@ static int device_coldplug(Unit *u) { + * 1. MANAGER_IS_RUNNING() == false + * 2. enumerate devices: manager_enumerate() -> device_enumerate() + * Device.enumerated_found is set. +- * 3. deserialize devices: manager_deserialize() -> device_deserialize() ++ * 3. deserialize devices: manager_deserialize() -> device_deserialize_item() + * Device.deserialize_state and Device.deserialized_found are set. + * 4. coldplug devices: manager_coldplug() -> device_coldplug() + * deserialized properties are copied to the main properties. +@@ -183,22 +183,28 @@ static int device_coldplug(Unit *u) { + * + * - On switch-root, the udev databse may be cleared, except for devices with sticky bit, i.e. + * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general, +- * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be +- * ignored, as udev rules in initramfs and the main system are often different. If the deserialized +- * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE. Unlike the other starting +- * mode, MANAGER_IS_SWITCHING_ROOT() is true when device_coldplug() and device_catchup() are called. +- * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd +- * will (re-)process all devices, and the Device.found and Device.state will be adjusted. ++ * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the ++ * Device.deserialized_found must be ignored, as udev rules in initrd and the main system are often ++ * different. If the deserialized state is DEVICE_PLUGGED, we need to downgrade it to ++ * DEVICE_TENTATIVE. Unlike the other starting mode, MANAGER_IS_SWITCHING_ROOT() is true when ++ * device_coldplug() and device_catchup() are called. Hence, let's conditionalize the operations by ++ * using the flag. After switch-root, systemd-udevd will (re-)process all devices, and the ++ * Device.found and Device.state will be adjusted. + * +- * - On reload or reexecute, we can trust enumerated_found, deserialized_found, and deserialized_state. +- * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by +- * device_catchup() or uevents. */ ++ * - On reload or reexecute, we can trust Device.enumerated_found, Device.deserialized_found, and ++ * Device.deserialized_state. Of course, deserialized parameters may be outdated, but the unit ++ * state can be adjusted later by device_catchup() or uevents. */ + + if (MANAGER_IS_SWITCHING_ROOT(m) && + !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) { +- found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ ++ ++ /* The device has not been enumerated. On switching-root, such situation is natural. See the ++ * above comment. To prevent problematic state transition active → dead → active, let's ++ * drop the DEVICE_FOUND_UDEV flag and downgrade state to DEVICE_TENTATIVE(activating). See ++ * issue #12953 and #23208. */ ++ found &= ~DEVICE_FOUND_UDEV; + if (state == DEVICE_PLUGGED) +- state = DEVICE_TENTATIVE; /* downgrade state */ ++ state = DEVICE_TENTATIVE; + } + + if (d->found == found && d->state == state) +-- +2.33.0 + diff --git a/backport-core-device-verify-device-syspath-on-switching-root.patch b/backport-core-device-verify-device-syspath-on-switching-root.patch new file mode 100644 index 00000000..eae111ed --- /dev/null +++ b/backport-core-device-verify-device-syspath-on-switching-root.patch @@ -0,0 +1,42 @@ +From b6c86ae28149c4abb2f0bd6acab13153382da9e7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 26 Oct 2022 01:18:05 +0900 +Subject: [PATCH] core/device: verify device syspath on switching root + +Otherwise, if a device is removed while switching root, then the +corresponding .device unit will never go to inactive state. + +This replaces the code dropped by cf1ac0cfe44997747b0f857a1d0b67cea1298272. + +Fixes #25106. +--- + src/core/device.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/core/device.c b/src/core/device.c +index 7e354b2b4a..6e07f2745b 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -305,6 +305,19 @@ static int device_coldplug(Unit *u) { + found &= ~DEVICE_FOUND_UDEV; + if (state == DEVICE_PLUGGED) + state = DEVICE_TENTATIVE; ++ ++ /* Also check the validity of the device syspath. Without this check, if the device was ++ * removed while switching root, it would never go to inactive state, as both Device.found ++ * and Device.enumerated_found do not have the DEVICE_FOUND_UDEV flag, so device_catchup() in ++ * device_update_found_one() does nothing in most cases. See issue #25106. Note that the ++ * syspath field is only serialized when systemd is sufficiently new and the device has been ++ * already processed by udevd. */ ++ if (d->deserialized_sysfs) { ++ _cleanup_(sd_device_unrefp) sd_device *dev = NULL; ++ ++ if (sd_device_new_from_syspath(&dev, d->deserialized_sysfs) < 0) ++ state = DEVICE_DEAD; ++ } + } + + if (d->found == found && d->state == state) +-- +2.33.0 + diff --git a/backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch b/backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch new file mode 100644 index 00000000..f0adf688 --- /dev/null +++ b/backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch @@ -0,0 +1,91 @@ +From d35fe8c0afaa55441608cb7bbfa4af908e1ea8e3 Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Thu, 5 May 2022 08:49:56 +0200 +Subject: [PATCH] core: introduce MANAGER_IS_SWITCHING_ROOT() helper function + +Will be used by the following commit. +--- + src/core/main.c | 3 +++ + src/core/manager.c | 6 ++++++ + src/core/manager.h | 6 ++++++ + 3 files changed, 15 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index 44261db..d7e37e8 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1767,6 +1767,8 @@ static int invoke_main_loop( + return 0; + + case MANAGER_SWITCH_ROOT: ++ manager_set_switching_root(m, true); ++ + if (!m->switch_root_init) { + r = prepare_reexecute(m, &arg_serialization, ret_fds, true); + if (r < 0) { +@@ -2619,6 +2621,7 @@ int main(int argc, char *argv[]) { + set_manager_defaults(m); + set_manager_settings(m); + manager_set_first_boot(m, first_boot); ++ manager_set_switching_root(m, arg_switched_root); + + /* Remember whether we should queue the default job */ + queue_default_job = !arg_serialization || arg_switched_root; +diff --git a/src/core/manager.c b/src/core/manager.c +index 722e4e6..cc9cbb7 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -735,6 +735,10 @@ static int manager_setup_sigchld_event_source(Manager *m) { + return 0; + } + ++void manager_set_switching_root(Manager *m, bool switching_root) { ++ m->switching_root = MANAGER_IS_SYSTEM(m) && switching_root; ++} ++ + int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **_m) { + _cleanup_(manager_freep) Manager *m = NULL; + int r; +@@ -1753,6 +1757,8 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + + manager_ready(m); + ++ manager_set_switching_root(m, false); ++ + return 0; + } + +diff --git a/src/core/manager.h b/src/core/manager.h +index daeb454..9450c5e 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -379,6 +379,9 @@ struct Manager { + char *switch_root; + char *switch_root_init; + ++ /* This is true before and after switching root. */ ++ bool switching_root; ++ + /* This maps all possible path prefixes to the units needing + * them. It's a hashmap with a path string as key and a Set as + * value where Unit objects are contained. */ +@@ -435,6 +438,8 @@ static inline usec_t manager_default_timeout_abort_usec(Manager *m) { + /* The objective is set to OK as soon as we enter the main loop, and set otherwise as soon as we are done with it */ + #define MANAGER_IS_RUNNING(m) ((m)->objective == MANAGER_OK) + ++#define MANAGER_IS_SWITCHING_ROOT(m) ((m)->switching_root) ++ + #define MANAGER_IS_TEST_RUN(m) ((m)->test_run_flags != 0) + + int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **m); +@@ -499,6 +504,7 @@ void manager_recheck_journal(Manager *m); + + void manager_set_show_status(Manager *m, ShowStatus mode); + void manager_set_first_boot(Manager *m, bool b); ++void manager_set_switching_root(Manager *m, bool switching_root); + + void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5); + void manager_flip_auto_status(Manager *m, bool enable); +-- +2.33.0 + diff --git a/backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch b/backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch new file mode 100644 index 00000000..6e0f2eef --- /dev/null +++ b/backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch @@ -0,0 +1,91 @@ +From bee6e755bb8e53a7a436e221b015ce0232ed87c0 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Wed, 10 May 2023 13:54:15 +0800 +Subject: [PATCH] core: only refuse Type=dbus service enqueuing if dbus has + stop job + +Follow-up for #27579 + +In #27579 we refused all StartUnit requests for Type=dbus units +if dbus is not running, which means if dbus is manually stopped, +user can't use systemctl to start Type=dbus units again, which +is incorrect. + +The only culprit that leads to the cancellation of the whole +transaction mentioned in #26799 is job type conflict on dbus. +So let's relax the restriction and only refuse job enqueuing +if dbus has a stop job. + +To summarize, the case we want to avoid is: + +1. dbus has a stop job installed +2. StartUnit/ActivationRequest is received +3. Type=dbus service gets started, which has Requires=dbus.socket +4. dbus is pulled in again, resulting in job type conflict + +What we can support is: + +1. dbus is already stopped +2. StartUnit is received (possibly through systemctl, i.e. on private bus) +3. Type=dbus service gets started, which will wait for dbus to start +4. dbus is started again, thus the job for Type=dbus service + +Replaces #27590 +Fixes #27588 +--- + src/core/dbus-unit.c | 32 +++++++++++++++++++++++++------- + 1 file changed, 25 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index 5427abe..a39de8c 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -1474,6 +1474,7 @@ int bus_unit_queue_job( + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_free_ char *job_path = NULL, *unit_path = NULL; + _cleanup_(set_freep) Set *affected = NULL; ++ const char *dbus_unit; + Iterator i; + Job *j, *a; + int r; +@@ -1506,13 +1507,30 @@ int bus_unit_queue_job( + (type == JOB_STOP && u->refuse_manual_stop) || + (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) || + (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start)) +- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id); +- +- /* dbus-broker issues StartUnit for activation requests, so let's apply the same check +- * used in signal_activation_request(). */ +- if (type == JOB_START && u->type == UNIT_SERVICE && +- SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager)) +- return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running."); ++ return sd_bus_error_setf(error, ++ BUS_ERROR_ONLY_BY_DEPENDENCY, ++ "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", ++ u->id); ++ ++ /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically ++ * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start ++ * job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting ++ * job enqueuing early. ++ * ++ * Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending() ++ * here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl ++ * to start Type=dbus services even when dbus is inactive. */ ++ if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS) ++ FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) { ++ Unit *dbus; ++ ++ dbus = manager_get_unit(u->manager, dbus_unit); ++ if (dbus && unit_stop_pending(dbus)) ++ return sd_bus_error_setf(error, ++ BUS_ERROR_SHUTTING_DOWN, ++ "Operation for unit %s refused, D-Bus is shutting down.", ++ u->id); ++ } + + if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) { + affected = set_new(NULL); +-- +2.33.0 + diff --git a/backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch b/backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch new file mode 100644 index 00000000..72edee8f --- /dev/null +++ b/backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch @@ -0,0 +1,43 @@ +From 53964fd26b4a01191609ffc064aa8ccccd28e377 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Tue, 9 May 2023 00:07:45 +0800 +Subject: [PATCH] core: refuse dbus activation if dbus is not running + +dbus-broker issues StartUnit directly for activation requests, +so let's add a check on bus state in bus_unit_queue_job to refuse +that if dbus is not running. + +Replaces #27570 +Closes #26799 +--- + src/core/dbus-unit.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index ef434fb..5427abe 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -19,6 +19,7 @@ + #include "process-util.h" + #include "selinux-access.h" + #include "signal-util.h" ++#include "service.h" + #include "special.h" + #include "string-table.h" + #include "string-util.h" +@@ -1507,6 +1508,12 @@ int bus_unit_queue_job( + (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start)) + return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id); + ++ /* dbus-broker issues StartUnit for activation requests, so let's apply the same check ++ * used in signal_activation_request(). */ ++ if (type == JOB_START && u->type == UNIT_SERVICE && ++ SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager)) ++ return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running."); ++ + if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) { + affected = set_new(NULL); + if (!affected) +-- +2.33.0 + diff --git a/backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch b/backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch new file mode 100644 index 00000000..48bbe6b7 --- /dev/null +++ b/backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch @@ -0,0 +1,113 @@ +From 7870de03c52982290f9b8ae11eb4d89db66f4be3 Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Thu, 5 May 2022 11:11:57 +0200 +Subject: [PATCH] core: replace m->honor_device_enumeration with + MANAGER_IS_SWITCHING_ROOT() + +--- + src/core/device.c | 7 +++---- + src/core/manager.c | 21 +-------------------- + src/core/manager.h | 2 -- + 3 files changed, 4 insertions(+), 26 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 5280edc..99666ab 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -185,9 +185,8 @@ static int device_coldplug(Unit *u) { + * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general, + * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be + * ignored, as udev rules in initramfs and the main system are often different. If the deserialized +- * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE (or DEVICE_DEAD if nobody +- * sees the device). Unlike the other starting mode, Manager.honor_device_enumeration == false +- * (maybe, it is better to rename the flag) when device_coldplug() and device_catchup() are called. ++ * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE. Unlike the other starting ++ * mode, MANAGER_IS_SWITCHING_ROOT() is true when device_coldplug() and device_catchup() are called. + * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd + * will (re-)process all devices, and the Device.found and Device.state will be adjusted. + * +@@ -195,7 +194,7 @@ static int device_coldplug(Unit *u) { + * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by + * device_catchup() or uevents. */ + +- if (!m->honor_device_enumeration && !MANAGER_IS_USER(m) && ++ if (MANAGER_IS_SWITCHING_ROOT(m) && + !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) { + found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ + if (state == DEVICE_PLUGGED) +diff --git a/src/core/manager.c b/src/core/manager.c +index cc9cbb7..ddb79b5 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1649,8 +1649,6 @@ static void manager_ready(Manager *m) { + + /* Let's finally catch up with any changes that took place while we were reloading/reexecing */ + manager_catchup(m); +- +- m->honor_device_enumeration = true; + } + + static Manager* manager_reloading_start(Manager *m) { +@@ -3186,9 +3184,6 @@ int manager_serialize( + (void) serialize_bool(f, "taint-logged", m->taint_logged); + (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs); + +- /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */ +- (void) serialize_bool(f, "honor-device-enumeration", !switching_root); +- + t = show_status_to_string(m->show_status); + if (t) + (void) serialize_item(f, "show-status", t); +@@ -3413,15 +3408,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + else + m->service_watchdogs = b; + +- } else if ((val = startswith(l, "honor-device-enumeration="))) { +- int b; +- +- b = parse_boolean(val); +- if (b < 0) +- log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val); +- else +- m->honor_device_enumeration = b; +- + } else if ((val = startswith(l, "show-status="))) { + ShowStatus s; + +@@ -3521,7 +3507,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + + if (q < _MANAGER_TIMESTAMP_MAX) /* found it */ + (void) deserialize_dual_timestamp(val, m->timestamps + q); +- else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */ ++ else if (!STARTSWITH_SET(l, "kdbus-fd=", "honor-device-enumeration=")) /* ignore deprecated values */ + log_notice("Unknown serialization item '%s', ignoring.", l); + } + } +@@ -3610,11 +3596,6 @@ int manager_reload(Manager *m) { + assert(m->n_reloading > 0); + m->n_reloading--; + +- /* On manager reloading, device tag data should exists, thus, we should honor the results of device +- * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So, +- * let's always set the flag here for safety. */ +- m->honor_device_enumeration = true; +- + manager_ready(m); + + m->send_reloading_done = true; +diff --git a/src/core/manager.h b/src/core/manager.h +index 9450c5e..eced504 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -419,8 +419,6 @@ struct Manager { + * multiple times on the same unit. */ + unsigned sigchldgen; + unsigned notifygen; +- +- bool honor_device_enumeration; + }; + + static inline usec_t manager_default_timeout_abort_usec(Manager *m) { +-- +2.33.0 + diff --git a/backport-core-timer-fix-memleak.patch b/backport-core-timer-fix-memleak.patch new file mode 100644 index 00000000..fdcf3448 --- /dev/null +++ b/backport-core-timer-fix-memleak.patch @@ -0,0 +1,61 @@ +From 82362b16ac842fc38340d21ebf39b259c5edaed3 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 10 May 2022 14:09:24 +0900 +Subject: [PATCH] core/timer: fix memleak + +Fixes #23326. + +(cherry picked from commit d3ab7b8078944db28bc621f43dd942a3c878fffb) +--- + src/core/timer.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index 7d81685..c810049 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -133,6 +133,7 @@ static int timer_add_trigger_dependencies(Timer *t) { + } + + static int timer_setup_persistent(Timer *t) { ++ _cleanup_free_ char *stamp_path = NULL; + int r; + + assert(t); +@@ -146,13 +147,13 @@ static int timer_setup_persistent(Timer *t) { + if (r < 0) + return r; + +- t->stamp_path = strjoin("/var/lib/systemd/timers/stamp-", UNIT(t)->id); ++ stamp_path = strjoin("/var/lib/systemd/timers/stamp-", UNIT(t)->id); + } else { + const char *e; + + e = getenv("XDG_DATA_HOME"); + if (e) +- t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id); ++ stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id); + else { + + _cleanup_free_ char *h = NULL; +@@ -161,14 +162,14 @@ static int timer_setup_persistent(Timer *t) { + if (r < 0) + return log_unit_error_errno(UNIT(t), r, "Failed to determine home directory: %m"); + +- t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id); ++ stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id); + } + } + +- if (!t->stamp_path) ++ if (!stamp_path) + return log_oom(); + +- return 0; ++ return free_and_replace(t->stamp_path, stamp_path); + } + + static int timer_load(Unit *u) { +-- +2.33.0 + diff --git a/backport-core-timer-fix-potential-use-after-free.patch b/backport-core-timer-fix-potential-use-after-free.patch new file mode 100644 index 00000000..a7e0d5c2 --- /dev/null +++ b/backport-core-timer-fix-potential-use-after-free.patch @@ -0,0 +1,26 @@ +From 38410e13ec9b1b67364f2f0af3b27d9e934bcd96 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 10 May 2022 14:10:17 +0900 +Subject: [PATCH] core/timer: fix potential use-after-free + +(cherry picked from commit 756491af392a99c4286d876b0041535e50df80ad) +--- + src/core/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index c810049..b0890c0 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -68,7 +68,7 @@ static void timer_done(Unit *u) { + t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source); + t->realtime_event_source = sd_event_source_unref(t->realtime_event_source); + +- free(t->stamp_path); ++ t->stamp_path = mfree(t->stamp_path); + } + + static int timer_verify(Timer *t) { +-- +2.33.0 + diff --git a/backport-core-unit-fix-use-after-free.patch b/backport-core-unit-fix-use-after-free.patch new file mode 100644 index 00000000..8dbe0cef --- /dev/null +++ b/backport-core-unit-fix-use-after-free.patch @@ -0,0 +1,30 @@ +From 3daae8785764304a65892ddcd548b6aae16c9463 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 9 May 2022 00:56:05 +0900 +Subject: [PATCH] core/unit: fix use-after-free + +Fixes #23312. + +(cherry picked from commit 734582830b58e000a26e18807ea277c18778573c) +--- + src/core/unit.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index fa8489c..5fe338f 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -608,8 +608,8 @@ void unit_free(Unit *u) { + + unit_dequeue_rewatch_pids(u); + +- sd_bus_slot_unref(u->match_bus_slot); +- sd_bus_track_unref(u->bus_track); ++ u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); ++ u->bus_track = sd_bus_track_unref(u->bus_track); + u->deserialized_refs = strv_free(u->deserialized_refs); + + unit_free_requires_mounts_for(u); +-- +2.33.0 + diff --git a/backport-manager-allow-transient-units-to-have-drop-ins.patch b/backport-manager-allow-transient-units-to-have-drop-ins.patch new file mode 100644 index 00000000..746ac733 --- /dev/null +++ b/backport-manager-allow-transient-units-to-have-drop-ins.patch @@ -0,0 +1,90 @@ +From 1a09fb995e0e84c2a5f40945248644b174863c6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Oct 2022 15:02:20 +0200 +Subject: [PATCH] manager: allow transient units to have drop-ins + +In https://github.com/containers/podman/issues/16107, starting of a transient +slice unit fails because there's a "global" drop-in +/usr/lib/systemd/user/slice.d/10-oomd-per-slice-defaults.conf (provided by +systemd-oomd-defaults package to install some default oomd policy). This means +that the unit_is_pristine() check fails and starting of the unit is forbidden. + +It seems pretty clear to me that dropins at any other level then the unit +should be ignored in this check: we now have multiple layers of drop-ins +(for each level of the cgroup path, and also "global" ones for a specific +unit type). If we install a "global" drop-in, we wouldn't be able to start +any transient units of that type, which seems undesired. + +In principle we could reject dropins at the unit level, but I don't think that +is useful. The whole reason for drop-ins is that they are "add ons", and there +isn't any particular reason to disallow them for transient units. It would also +make things harder to implement and describe: one place for drop-ins is good, +but another is bad. (And as a corner case: for instanciated units, a drop-in +in the template would be acceptable, but a instance-specific drop-in bad?) + +Thus, $subject. + +While at it, adjust the message. All the conditions in unit_is_pristine() +essentially mean that it wasn't loaded (e.g. it might be in an error state), +and that it doesn't have a fragment path (now that drop-ins are acceptable). +If there's a job for it, it necessarilly must have been loaded. If it is +merged into another unit, it also was loaded and found to be an alias. +Based on the discussion in the bugs, it seems that the current message +is far from obvious ;) + +Fixes https://github.com/containers/podman/issues/16107, +https://bugzilla.redhat.com/show_bug.cgi?id=2133792. + +(cherry picked from commit 1f83244641f13a9cb28fdac7e3c17c5446242dfb) +(cherry picked from commit 98a45608c4bf5aa1ba9b603ac2e5730f13659d88) +--- + src/core/dbus-manager.c | 3 ++- + src/core/unit.c | 14 ++++++++------ + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index c7ba696..1f6fa8f 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -776,7 +776,8 @@ static int transient_unit_from_message( + return r; + + if (!unit_is_pristine(u)) +- return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name); ++ return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, ++ "Unit %s was already loaded or has a fragment file.", name); + + /* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +diff --git a/src/core/unit.c b/src/core/unit.c +index dc608ab..75892cd 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5014,16 +5014,18 @@ int unit_fail_if_noncanonical(Unit *u, const char* where) { + bool unit_is_pristine(Unit *u) { + assert(u); + +- /* Check if the unit already exists or is already around, +- * in a number of different ways. Note that to cater for unit +- * types such as slice, we are generally fine with units that +- * are marked UNIT_LOADED even though nothing was actually +- * loaded, as those unit types don't require a file on disk. */ ++ /* Check if the unit already exists or is already around, in a number of different ways. Note that to ++ * cater for unit types such as slice, we are generally fine with units that are marked UNIT_LOADED ++ * even though nothing was actually loaded, as those unit types don't require a file on disk. ++ * ++ * Note that we don't check for drop-ins here, because we allow drop-ins for transient units ++ * identically to non-transient units, both unit-specific and hierarchical. E.g. for a-b-c.service: ++ * service.d/….conf, a-.service.d/….conf, a-b-.service.d/….conf, a-b-c.service.d/….conf. ++ */ + + return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && + !u->fragment_path && + !u->source_path && +- strv_isempty(u->dropin_paths) && + !u->job && + !u->merged_into; + } +-- +2.33.0 + diff --git a/backport-manager-reformat-boolean-expression-in-unit_is_prist.patch b/backport-manager-reformat-boolean-expression-in-unit_is_prist.patch new file mode 100644 index 00000000..7a0d94dd --- /dev/null +++ b/backport-manager-reformat-boolean-expression-in-unit_is_prist.patch @@ -0,0 +1,40 @@ +From b146a7345b69de16e88347acadb3783ffeeaad9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Oct 2022 14:40:24 +0200 +Subject: [PATCH] manager: reformat boolean expression in unit_is_pristine() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Not not IN_SET(…) is just too much for my poor brain. Let's invert +the expression to make it easier to undertand. +--- + src/core/unit.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index d6bea2080f..5016114cb4 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4850,12 +4850,12 @@ bool unit_is_pristine(Unit *u) { + * are marked UNIT_LOADED even though nothing was actually + * loaded, as those unit types don't require a file on disk. */ + +- return !(!IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) || +- u->fragment_path || +- u->source_path || +- !strv_isempty(u->dropin_paths) || +- u->job || +- u->merged_into); ++ return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && ++ !u->fragment_path && ++ !u->source_path && ++ strv_isempty(u->dropin_paths) && ++ !u->job && ++ !u->merged_into; + } + + pid_t unit_control_pid(Unit *u) { +-- +2.33.0 + diff --git a/backport-sd-event-always-initialize-sd_event.perturb.patch b/backport-sd-event-always-initialize-sd_event.perturb.patch new file mode 100644 index 00000000..8b283617 --- /dev/null +++ b/backport-sd-event-always-initialize-sd_event.perturb.patch @@ -0,0 +1,59 @@ +From f1a8b69808777aff37c036fd94a0275873d12407 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 23 Feb 2023 07:31:01 +0900 +Subject: [PATCH] sd-event: always initialize sd_event.perturb + +If the boot ID cannot be obtained, let's first fallback to the machine +ID, and if still cannot, then let's use 0. +Otherwise, no timer event source cannot be triggered. + +Fixes #26549. + +(cherry picked from commit 6d2326e036ceed30f9ccdb0266713c10a44dcf6c) +(cherry picked from commit 58c821af607b61738b7b72ad1452e70f648689a6) +(cherry picked from commit 78976199b2e016600c3f7cf8f39747c9ef6c853b) +(cherry picked from commit ac04d804c30f519918866fb4eeb3bc4a9cbadd43) +--- + src/libsystemd/sd-event/sd-event.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 89accdce00..37565b17be 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1126,22 +1126,21 @@ _public_ int sd_event_add_io( + } + + static void initialize_perturb(sd_event *e) { +- sd_id128_t bootid = {}; ++ sd_id128_t id = {}; + +- /* When we sleep for longer, we try to realign the wakeup to +- the same time within each minute/second/250ms, so that +- events all across the system can be coalesced into a single +- CPU wakeup. However, let's take some system-specific +- randomness for this value, so that in a network of systems +- with synced clocks timer events are distributed a +- bit. Here, we calculate a perturbation usec offset from the +- boot ID. */ ++ /* When we sleep for longer, we try to realign the wakeup to the same time within each ++ * minute/second/250ms, so that events all across the system can be coalesced into a single CPU ++ * wakeup. However, let's take some system-specific randomness for this value, so that in a network ++ * of systems with synced clocks timer events are distributed a bit. Here, we calculate a ++ * perturbation usec offset from the boot ID (or machine ID if failed, e.g. /proc is not mounted). */ + + if (_likely_(e->perturb != USEC_INFINITY)) + return; + +- if (sd_id128_get_boot(&bootid) >= 0) +- e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE; ++ if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) > 0) ++ e->perturb = (id.qwords[0] ^ id.qwords[1]) % USEC_PER_MINUTE; ++ else ++ e->perturb = 0; /* This is a super early process without /proc and /etc ?? */ + } + + static int event_setup_timer_fd( +-- +2.33.0 + diff --git a/backport-sd-event-fix-error-handling.patch b/backport-sd-event-fix-error-handling.patch new file mode 100644 index 00000000..a0b07c45 --- /dev/null +++ b/backport-sd-event-fix-error-handling.patch @@ -0,0 +1,31 @@ +From 056fbe84ef67168adcaf41baa37de1b712f6fb74 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 23 Feb 2023 07:31:01 +0900 +Subject: [PATCH] sd-event: fix error handling + +Follow-up for 6d2326e036ceed30f9ccdb0266713c10a44dcf6c. + +(cherry picked from commit 1912f790fee9e0182acd77b77496f500094a140d) +(cherry picked from commit a719c2ec2f410f8b979cec04dcdac9af470ee52b) +(cherry picked from commit dd6561ff3e12314d41954b7ea8e3627101931a18) +(cherry picked from commit 8be4af42044969bc268b32ffe9570cee733fecf6) +--- + src/libsystemd/sd-event/sd-event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 37565b17be..df4d9037ac 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1137,7 +1137,7 @@ static void initialize_perturb(sd_event *e) { + if (_likely_(e->perturb != USEC_INFINITY)) + return; + +- if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) > 0) ++ if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) >= 0) + e->perturb = (id.qwords[0] ^ id.qwords[1]) % USEC_PER_MINUTE; + else + e->perturb = 0; /* This is a super early process without /proc and /etc ?? */ +-- +2.33.0 + diff --git a/backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch b/backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch new file mode 100644 index 00000000..fbc2b69d --- /dev/null +++ b/backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch @@ -0,0 +1,27 @@ +From 5e069e405a73ff5a406598436fe21d6dabbb281c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 4 May 2022 16:05:04 +0900 +Subject: [PATCH] sd-lldp: use memcpy_safe() as the buffer size may be zero + +(cherry picked from commit 87bd4b79e692f384c2190c9b3824df4853333018) +--- + src/libsystemd-network/lldp-neighbor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c +index 372bc2ef93..bc98235ce1 100644 +--- a/src/libsystemd-network/lldp-neighbor.c ++++ b/src/libsystemd-network/lldp-neighbor.c +@@ -652,7 +652,8 @@ int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t ra + if (!n) + return -ENOMEM; + +- memcpy(LLDP_NEIGHBOR_RAW(n), raw, raw_size); ++ memcpy_safe(LLDP_NEIGHBOR_RAW(n), raw, raw_size); ++ + r = lldp_neighbor_parse(n); + if (r < 0) + return r; +-- +2.33.0 + diff --git a/backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch b/backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch new file mode 100644 index 00000000..bd18b74a --- /dev/null +++ b/backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch @@ -0,0 +1,31 @@ +From 412b89a6e8055f2c8c9db4b6b847f081e00461ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 6 May 2022 17:36:47 +0200 +Subject: [PATCH] shared/bootspec: avoid crashing on config without a value + +(cherry picked from commit b6bd2562ebb01b48cdb55a970d9daa1799b59876) +--- + src/shared/bootspec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c +index 0076092c2a..9e2b2899bd 100644 +--- a/src/shared/bootspec.c ++++ b/src/shared/bootspec.c +@@ -124,6 +124,13 @@ static int boot_entry_load( + continue; + } + ++ if (isempty(p)) { ++ /* Some fields can reasonably have an empty value. In other cases warn. */ ++ if (!STR_IN_SET(field, "options", "devicetree-overlay")) ++ log_warning("%s:%u: Field %s without value", tmp.path, line, field); ++ continue; ++ } ++ + if (streq(field, "title")) + r = free_and_strdup(&tmp.title, p); + else if (streq(field, "version")) +-- +2.33.0 + diff --git a/backport-timedatectl-fix-a-memory-leak.patch b/backport-timedatectl-fix-a-memory-leak.patch new file mode 100644 index 00000000..9cf4c200 --- /dev/null +++ b/backport-timedatectl-fix-a-memory-leak.patch @@ -0,0 +1,46 @@ +From 71d2356edffafe8c40797c64f6fb82a8885d1da9 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Wed, 4 May 2022 11:35:19 +0000 +Subject: [PATCH] timedatectl: fix a memory leak + +``` +timedatectl list-timezones --no-pager +... +==164329==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 8192 byte(s) in 1 object(s) allocated from: + #0 0x7fe8a74b6f8c in reallocarray (/lib64/libasan.so.6+0xaef8c) + #1 0x7fe8a63485dc in strv_push ../src/basic/strv.c:419 + #2 0x7fe8a6349419 in strv_consume ../src/basic/strv.c:490 + #3 0x7fe8a634958d in strv_extend ../src/basic/strv.c:542 + #4 0x7fe8a643d787 in bus_message_read_strv_extend ../src/libsystemd/sd-bus/bus-message.c:5606 + #5 0x7fe8a643db9d in sd_bus_message_read_strv ../src/libsystemd/sd-bus/bus-message.c:5628 + #6 0x4085fb in list_timezones ../src/timedate/timedatectl.c:314 + #7 0x7fe8a61ef3e1 in dispatch_verb ../src/shared/verbs.c:103 + #8 0x410f91 in timedatectl_main ../src/timedate/timedatectl.c:1025 + #9 0x41111c in run ../src/timedate/timedatectl.c:1043 + #10 0x411242 in main ../src/timedate/timedatectl.c:1046 + #11 0x7fe8a489df1f in __libc_start_call_main (/lib64/libc.so.6+0x40f1f) +``` + +(cherry picked from commit a2e37d52312806b1847800df2358e61276cda052) +--- + src/timedate/timedatectl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c +index 4553699..889966d 100644 +--- a/src/timedate/timedatectl.c ++++ b/src/timedate/timedatectl.c +@@ -287,7 +287,7 @@ static int list_timezones(int argc, char **argv, void *userdata) { + sd_bus *bus = userdata; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + int r; +- char** zones; ++ _cleanup_strv_free_ char **zones = NULL; + + r = sd_bus_call_method(bus, + "org.freedesktop.timedate1", +-- +2.33.0 + diff --git a/backport-udev-cdrom_id-check-last-track-info.patch b/backport-udev-cdrom_id-check-last-track-info.patch new file mode 100644 index 00000000..6b96368b --- /dev/null +++ b/backport-udev-cdrom_id-check-last-track-info.patch @@ -0,0 +1,31 @@ +From c3fcff52912b0323e11f535fce151dc758f111e6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 14 Aug 2022 06:00:10 +0900 +Subject: [PATCH] udev/cdrom_id: check last track info + +Fixes off-by-one issue. + +Fixes #24306. + +(cherry picked from commit 628998ecfa0d39b38874e1aecdb28022f80f3269) +(cherry picked from commit c67a388aeffcdc27ff280f01b7939005f7a9c8e9) +--- + src/udev/cdrom_id/cdrom_id.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c +index a287901..50a5821 100644 +--- a/src/udev/cdrom_id/cdrom_id.c ++++ b/src/udev/cdrom_id/cdrom_id.c +@@ -772,7 +772,7 @@ static int cd_media_toc(int fd) { + /* Take care to not iterate beyond the last valid track as specified in + * the TOC, but also avoid going beyond the TOC length, just in case + * the last track number is invalidly large */ +- for (p = toc+4, i = 4; i < len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) { ++ for (p = toc+4, i = 4; i <= len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) { + unsigned block; + unsigned is_data_track; + +-- +2.33.0 + diff --git a/systemd.spec b/systemd.spec index bfbb03a6..307a31ec 100644 --- a/systemd.spec +++ b/systemd.spec @@ -16,7 +16,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd Version: 243 -Release: 61 +Release: 62 License: MIT and LGPLv2+ and GPLv2+ Summary: System and Service Manager @@ -199,6 +199,28 @@ Patch0149: backport-argv-util-also-update-program_invocation_short_name.pat Patch0150: backport-pid1-fix-segv-triggered-by-status-query.patch Patch0151: backport-main-log-which-process-send-SIGNAL-to-PID1.patch Patch0152: backport-main-drop-get_process_cmdline-from-crash-handler.patch +Patch0153: backport-timedatectl-fix-a-memory-leak.patch +Patch0154: backport-core-unit-fix-use-after-free.patch +Patch0155: backport-core-timer-fix-memleak.patch +Patch0156: backport-core-timer-fix-potential-use-after-free.patch +Patch0157: backport-udev-cdrom_id-check-last-track-info.patch +Patch0158: backport-manager-reformat-boolean-expression-in-unit_is_prist.patch +Patch0159: backport-manager-allow-transient-units-to-have-drop-ins.patch +Patch0160: backport-sd-event-always-initialize-sd_event.perturb.patch +Patch0161: backport-sd-event-fix-error-handling.patch +Patch0162: backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch +Patch0163: backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch +Patch0164: backport-core-device-drop-unnecessary-condition.patch +Patch0165: backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch +Patch0166: backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch +Patch0167: backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch +Patch0168: backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch +Patch0169: backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch +Patch0170: backport-core-device-update-comment.patch +Patch0171: backport-core-device-also-serialize-deserialize-device-syspat.patch +Patch0172: backport-core-device-verify-device-syspath-on-switching-root.patch +Patch0173: backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch +Patch0174: backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch #openEuler Patch9002: 1509-fix-journal-file-descriptors-leak-problems.patch @@ -1704,6 +1726,9 @@ fi %exclude /usr/share/man/man3/* %changelog +* Fri Jun 16 2023 hongjinghao - 243-62 +- sync community patches + * Sun Apr 23 2023 hongjinghao - 243-61 - sync community patches -- Gitee