diff --git a/1070-core-validate-input-cgroup-path-more-prudently.patch b/1070-core-validate-input-cgroup-path-more-prudently.patch new file mode 100644 index 0000000..bd483be --- /dev/null +++ b/1070-core-validate-input-cgroup-path-more-prudently.patch @@ -0,0 +1,29 @@ +From 370592c9cac2c6ab5d039a5dc8ca41004bc922b6 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 26 Feb 2026 11:06:34 +0100 +Subject: [PATCH] core: validate input cgroup path more prudently + +(cherry picked from commit efa6ba2ab625aaa160ac435a09e6482fc63bdbe8) + +Resolves: RHEL-152085 +--- + src/core/dbus-manager.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index ea2f3e7f59..99f6d80343 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -456,6 +456,12 @@ static int method_get_unit_by_control_group(sd_bus_message *message, void *userd + if (r < 0) + return r; + ++ if (!path_is_absolute(cgroup)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not absolute: %s", cgroup); ++ ++ if (!path_is_normalized(cgroup)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not normalized: %s", cgroup); ++ + u = manager_get_unit_by_cgroup(m, cgroup); + if (!u) + return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Control group '%s' is not valid or not managed by this instance", cgroup); diff --git a/1071-nspawn-normalize-pivot_root-paths.patch b/1071-nspawn-normalize-pivot_root-paths.patch new file mode 100644 index 0000000..6965b52 --- /dev/null +++ b/1071-nspawn-normalize-pivot_root-paths.patch @@ -0,0 +1,32 @@ +From dc7652fb1246dd36bc673eaa5d9008f7d72fbb6f Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 11 Mar 2026 13:27:14 +0000 +Subject: [PATCH] nspawn: normalize pivot_root paths + +Originally reported on yeswehack.com as: +YWH-PGM9780-116 + +Follow-up for b53ede699cdc5233041a22591f18863fb3fe2672 + +(cherry picked from commit 7b85f5498a958e5bb660c703b8f4a71cceed3373) + +Resolves: RHEL-163868 +--- + src/nspawn/nspawn-mount.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c +index b5df65e2a4..5a4115c86d 100644 +--- a/src/nspawn/nspawn-mount.c ++++ b/src/nspawn/nspawn-mount.c +@@ -1410,7 +1410,9 @@ int pivot_root_parse(char **pivot_root_new, char **pivot_root_old, const char *s + + if (!path_is_absolute(root_new)) + return -EINVAL; +- if (root_old && !path_is_absolute(root_old)) ++ if (!path_is_normalized(root_new)) ++ return -EINVAL; ++ if (root_old && (!path_is_absolute(root_old) || !path_is_normalized(root_old))) + return -EINVAL; + + free_and_replace(*pivot_root_new, root_new); diff --git a/1072-udev-check-for-invalid-chars-in-various-fields-recei.patch b/1072-udev-check-for-invalid-chars-in-various-fields-recei.patch new file mode 100644 index 0000000..aba7d3d --- /dev/null +++ b/1072-udev-check-for-invalid-chars-in-various-fields-recei.patch @@ -0,0 +1,95 @@ +From debeafd9ba05c33e53d1c4b2d681b22aacfe6bd6 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 6 Mar 2026 19:32:35 +0000 +Subject: [PATCH] udev: check for invalid chars in various fields received from + the kernel + +(cherry picked from commit 16325b35fa6ecb25f66534a562583ce3b96d52f3) + +Resolves: RHEL-163874 +--- + src/udev/scsi_id/scsi_id.c | 5 +++-- + src/udev/udev-builtin-net_id.c | 9 +++++++++ + src/udev/v4l_id/v4l_id.c | 5 ++++- + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c +index 5caab7774f..86923ae416 100644 +--- a/src/udev/scsi_id/scsi_id.c ++++ b/src/udev/scsi_id/scsi_id.c +@@ -25,6 +25,7 @@ + #include "scsi_id.h" + #include "string-util.h" + #include "udev-util.h" ++#include "utf8.h" + + static const struct option options[] = { + { "device", required_argument, NULL, 'd' }, +@@ -532,8 +533,8 @@ static int scsi_id(struct udev *udev, char *maj_min_dev) + } + if (dev_scsi.tgpt_group[0] != '\0') + printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group); +- if (dev_scsi.unit_serial_number[0] != '\0') +- printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number); ++ if (dev_scsi.unit_serial_number[0] != '\0' && utf8_is_valid(dev_scsi.unit_serial_number) && !string_has_cc(dev_scsi.unit_serial_number, /* ok= */ NULL)) ++ printf("ID_SCSI_SERIAL=%s\n", serial_str); + goto out; + } + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ece5d29205..a8675acede 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -103,6 +103,7 @@ + #include "string-util.h" + #include "udev.h" + #include "udev-util.h" ++#include "utf8.h" + + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) +@@ -374,6 +375,10 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { + + /* kernel provided front panel port name for multiple port PCI device */ + port_name = udev_device_get_sysattr_value(dev, "phys_port_name"); ++ if (port_name && (!utf8_is_valid(port_name) || string_has_cc(port_name, /* ok= */ NULL))) { ++ log_debug("Invalid phys_port_name"); ++ return -EINVAL; ++ } + + s = names->pci_onboard; + l = sizeof(names->pci_onboard); +@@ -464,6 +469,10 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + + /* kernel provided front panel port name for multiple port PCI device */ + port_name = udev_device_get_sysattr_value(dev, "phys_port_name"); ++ if (port_name && (!utf8_is_valid(port_name) || string_has_cc(port_name, /* ok= */ NULL))) { ++ log_debug("Invalid phys_port_name"); ++ return -EINVAL; ++ } + + /* compose a name based on the raw kernel's PCI bus, slot numbers */ + s = names->pci_path; +diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c +index 4d482891a1..bda704f115 100644 +--- a/src/udev/v4l_id/v4l_id.c ++++ b/src/udev/v4l_id/v4l_id.c +@@ -27,6 +27,8 @@ + #include + + #include "fd-util.h" ++#include "string-util.h" ++#include "utf8.h" + #include "util.h" + + int main(int argc, char *argv[]) { +@@ -65,7 +67,8 @@ int main(int argc, char *argv[]) { + + if (ioctl(fd, VIDIOC_QUERYCAP, &v2cap) == 0) { + printf("ID_V4L_VERSION=2\n"); +- printf("ID_V4L_PRODUCT=%s\n", v2cap.card); ++ if (utf8_is_valid((char *)v2cap.card) && !string_has_cc((char *)v2cap.card, /* ok= */ NULL)) ++ printf("ID_V4L_PRODUCT=%s\n", v2cap.card); + printf("ID_V4L_CAPABILITIES=:"); + if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0 || + (v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) > 0) diff --git a/1073-udev-fix-review-mixup.patch b/1073-udev-fix-review-mixup.patch new file mode 100644 index 0000000..f0b3c40 --- /dev/null +++ b/1073-udev-fix-review-mixup.patch @@ -0,0 +1,32 @@ +From 7b3ecb47c5c54169e384438eaf24baa382b83527 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 13 Mar 2026 11:10:47 +0000 +Subject: [PATCH] udev: fix review mixup + +The previous version in the PR changed variable and sanitized it +in place. The second version switched to skip if CCs are in the +string instead, but didn't move back to the original variable. +Because it's an existing variable, no CI caught it. + +Follow-up for 16325b35fa6ecb25f66534a562583ce3b96d52f3 + +(cherry picked from commit 54f880b02ecf7362e630ffc885d1466df6ee6820) + +Resolves: RHEL-163874 +--- + src/udev/scsi_id/scsi_id.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c +index 86923ae416..f6fa81d739 100644 +--- a/src/udev/scsi_id/scsi_id.c ++++ b/src/udev/scsi_id/scsi_id.c +@@ -534,7 +534,7 @@ static int scsi_id(struct udev *udev, char *maj_min_dev) + if (dev_scsi.tgpt_group[0] != '\0') + printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group); + if (dev_scsi.unit_serial_number[0] != '\0' && utf8_is_valid(dev_scsi.unit_serial_number) && !string_has_cc(dev_scsi.unit_serial_number, /* ok= */ NULL)) +- printf("ID_SCSI_SERIAL=%s\n", serial_str); ++ printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number); + goto out; + } + diff --git a/1074-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch b/1074-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch new file mode 100644 index 0000000..4f4038e --- /dev/null +++ b/1074-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch @@ -0,0 +1,52 @@ +From 48edc873b4acdfd9b9e0b781330090f72cebbdb8 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 10 Apr 2026 19:04:04 +0100 +Subject: [PATCH] udev/scsi-id: check for invalid chars in various fields + received from the kernel + +Follow-up for 16325b35fa6ecb25f66534a562583ce3b96d52f3 + +(cherry picked from commit 5f700d148c44063c0f0dbb9fc136866339cd3fa7) + +Related: RHEL-163874 +--- + src/udev/scsi_id/scsi_id.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c +index f6fa81d739..62bceffb8c 100644 +--- a/src/udev/scsi_id/scsi_id.c ++++ b/src/udev/scsi_id/scsi_id.c +@@ -479,6 +479,10 @@ static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, co + return 0; + } + ++static bool scsi_string_is_valid(const char *s) { ++ return !isempty(s) && utf8_is_valid(s) && !string_has_cc(s, /* ok= */ NULL); ++} ++ + /* + * scsi_id: try to get an id, if one is found, printf it to stdout. + * returns a value passed to exit() - 0 if printed an id, else 1. +@@ -523,17 +527,17 @@ static int scsi_id(struct udev *udev, char *maj_min_dev) + util_replace_chars(serial_str, NULL); + printf("ID_SERIAL_SHORT=%s\n", serial_str); + } +- if (dev_scsi.wwn[0] != '\0') { ++ if (scsi_string_is_valid(dev_scsi.wwn)) { + printf("ID_WWN=0x%s\n", dev_scsi.wwn); +- if (dev_scsi.wwn_vendor_extension[0] != '\0') { ++ if (scsi_string_is_valid(dev_scsi.wwn_vendor_extension)) { + printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension); + printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension); + } else + printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn); + } +- if (dev_scsi.tgpt_group[0] != '\0') ++ if (scsi_string_is_valid(dev_scsi.tgpt_group)) + printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group); +- if (dev_scsi.unit_serial_number[0] != '\0' && utf8_is_valid(dev_scsi.unit_serial_number) && !string_has_cc(dev_scsi.unit_serial_number, /* ok= */ NULL)) ++ if (scsi_string_is_valid(dev_scsi.unit_serial_number)) + printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number); + goto out; + } diff --git a/1075-core-manager-fix-memory-leak.patch b/1075-core-manager-fix-memory-leak.patch new file mode 100644 index 0000000..c46290c --- /dev/null +++ b/1075-core-manager-fix-memory-leak.patch @@ -0,0 +1,31 @@ +From 46cf6e2e8f20dfe0dcb6694bd9706a225533a0dd Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 16 Apr 2026 12:27:25 +0200 +Subject: [PATCH] core/manager: fix memory leak + +Follow-up for 63899267ba57ab4b0b11c039f5c6b03a78528aa7 + +RHEL-only + +Resolves: RHEL-163867 +--- + src/core/manager.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index d95a6db77c..51325f0212 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1812,8 +1812,10 @@ int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error + + /* Only activate the transaction if it contains jobs other than NOP anchor. + * Short-circuiting here avoids unnecessary processing, such as emitting D-Bus signals. */ +- if (hashmap_size(tr->jobs) <= 1) +- return 0; ++ if (hashmap_size(tr->jobs) <= 1) { ++ r = 0; ++ goto tr_abort; ++ } + + r = transaction_activate(tr, m, mode, NULL, e); + if (r < 0) diff --git a/systemd.spec b/systemd.spec index 095549a..1d0bb32 100644 --- a/systemd.spec +++ b/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 82%{?dist}.15 +Release: 82%{?dist}.16 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -1119,6 +1119,12 @@ Patch1066: 1066-resolved-add-dns_query_candidate_freep.patch Patch1067: 1067-resolved-fix-use-after-free-with-queries-hitting-the.patch Patch1068: 1068-resolve-exit-from-loop-for-transactions-when-transac.patch Patch1069: 1069-locale-util-do-not-call-setlocale-when-multi-threade.patch +Patch1070: 1070-core-validate-input-cgroup-path-more-prudently.patch +Patch1071: 1071-nspawn-normalize-pivot_root-paths.patch +Patch1072: 1072-udev-check-for-invalid-chars-in-various-fields-recei.patch +Patch1073: 1073-udev-fix-review-mixup.patch +Patch1074: 1074-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch +Patch1075: 1075-core-manager-fix-memory-leak.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1745,6 +1751,14 @@ fi %files tests -f .file-list-tests %changelog +* Thu Apr 16 2026 systemd maintenance team - 239-82.16 +- core: validate input cgroup path more prudently (RHEL-152085) +- nspawn: normalize pivot_root paths (RHEL-163868) +- udev: check for invalid chars in various fields received from the kernel (RHEL-163874) +- udev: fix review mixup (RHEL-163874) +- udev/scsi-id: check for invalid chars in various fields received from the kernel (RHEL-163874) +- core/manager: fix memory leak (RHEL-163867) + * Fri Jan 30 2026 systemd maintenance team - 239-82.15 - resolved: add dns_query_candidate_freep() (RHEL-93425) - resolved: fix use-after-free with queries hitting the cache (RHEL-93425)