diff --git a/SOURCES/1326-integritysetup-Add-support-for-hmac-sha512.patch b/SOURCES/1326-integritysetup-Add-support-for-hmac-sha512.patch new file mode 100644 index 0000000..c7e366e --- /dev/null +++ b/SOURCES/1326-integritysetup-Add-support-for-hmac-sha512.patch @@ -0,0 +1,78 @@ +From 24eef4e6cc9bde4b96d72fbd5b438d774f1ce66a Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Tue, 5 Mar 2024 08:28:40 +0100 +Subject: [PATCH] integritysetup: Add support for hmac-sha512 + +Currently the only supported integrity algorithm using HMAC is 'hmac-sha256'. +Add 'hmac-sha512' to the list of supported algorithms as well. + +(cherry picked from commit 7bf1cfe3b20037f3732d8854833b00f6a3511d95) + +Resolves: RHEL-50213 +--- + man/integritytab.xml | 6 +++--- + src/integritysetup/integrity-util.c | 2 +- + src/integritysetup/integrity-util.h | 1 + + src/integritysetup/integritysetup.c | 2 ++ + 4 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/man/integritytab.xml b/man/integritytab.xml +index 44f0a55929..2c48d2960f 100644 +--- a/man/integritytab.xml ++++ b/man/integritytab.xml +@@ -55,8 +55,8 @@ + + The third field if present contains an absolute filename path to a key file or a - + to specify none. When the filename is present, the "integrity-algorithm" defaults to hmac-sha256 +- with the key length derived from the number of bytes in the key file. At this time the only supported integrity algorithm +- when using key file is hmac-sha256. The maximum size of the key file is 4096 bytes. ++ with the key length derived from the number of bytes in the key file. At this time the only supported integrity algorithms ++ when using key file are hmac-sha256 and hmac-sha512. The maximum size of the key file is 4096 bytes. + + + The fourth field, if present, is a comma-delimited list of options or a - to specify none. The following options are +@@ -101,7 +101,7 @@ + + + +- ++ + + + The algorithm used for integrity checking. The default is crc32c. Must match option used during format. +diff --git a/src/integritysetup/integrity-util.c b/src/integritysetup/integrity-util.c +index 410133b377..934e97fa5e 100644 +--- a/src/integritysetup/integrity-util.c ++++ b/src/integritysetup/integrity-util.c +@@ -7,7 +7,7 @@ + #include "percent-util.h" + + static int supported_integrity_algorithm(char *user_supplied) { +- if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256")) ++ if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256", "hmac-sha512")) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported integrity algorithm (%s)", user_supplied); + return 0; + } +diff --git a/src/integritysetup/integrity-util.h b/src/integritysetup/integrity-util.h +index 359d2556a4..f701b59273 100644 +--- a/src/integritysetup/integrity-util.h ++++ b/src/integritysetup/integrity-util.h +@@ -15,4 +15,5 @@ int parse_integrity_options( + char **ret_integrity_alg); + + #define DM_HMAC_256 "hmac(sha256)" ++#define DM_HMAC_512 "hmac(sha512)" + #define DM_MAX_KEY_SIZE 4096 /* Maximum size of key allowed for dm-integrity */ +diff --git a/src/integritysetup/integritysetup.c b/src/integritysetup/integritysetup.c +index a602886cb3..674131ed54 100644 +--- a/src/integritysetup/integritysetup.c ++++ b/src/integritysetup/integritysetup.c +@@ -80,6 +80,8 @@ static const char *integrity_algorithm_select(const void *key_file_buf) { + if (arg_integrity_algorithm) { + if (streq("hmac-sha256", arg_integrity_algorithm)) + return DM_HMAC_256; ++ if (streq("hmac-sha512", arg_integrity_algorithm)) ++ return DM_HMAC_512; + return arg_integrity_algorithm; + } else if (key_file_buf) + return DM_HMAC_256; diff --git a/SOURCES/1327-integritysetup-Add-PHMAC-algorithm-to-list-of-known-.patch b/SOURCES/1327-integritysetup-Add-PHMAC-algorithm-to-list-of-known-.patch new file mode 100644 index 0000000..886a20d --- /dev/null +++ b/SOURCES/1327-integritysetup-Add-PHMAC-algorithm-to-list-of-known-.patch @@ -0,0 +1,84 @@ +From 2ce62a32b85b8bc756c34d31d10d343bd2c088f5 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Mon, 4 Mar 2024 09:26:18 +0100 +Subject: [PATCH] integritysetup: Add PHMAC algorithm to list of known + algorithms + +Add the PHMAC integrity algorithm to the list of supported algorithms. + +The PHMAC algorithm is like the regular HMAC algorithm, but it takes a wrapped key +as input. A key for the PHMAC algorithm is an opaque key blob, who's physical size +has nothing to do with the cryptographic size. Currently PHMAC is only available +for the s390x architecture. + +(cherry picked from commit eb7b0d413e5f7ca35e9f6a0b211dd71a710cb60d) + +Resolves: RHEL-50213 +--- + man/integritytab.xml | 4 ++-- + src/integritysetup/integrity-util.c | 2 +- + src/integritysetup/integrity-util.h | 2 ++ + src/integritysetup/integritysetup.c | 4 ++++ + 4 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/man/integritytab.xml b/man/integritytab.xml +index 2c48d2960f..f3f2a823c6 100644 +--- a/man/integritytab.xml ++++ b/man/integritytab.xml +@@ -56,7 +56,7 @@ + The third field if present contains an absolute filename path to a key file or a - + to specify none. When the filename is present, the "integrity-algorithm" defaults to hmac-sha256 + with the key length derived from the number of bytes in the key file. At this time the only supported integrity algorithms +- when using key file are hmac-sha256 and hmac-sha512. The maximum size of the key file is 4096 bytes. ++ when using key file are hmac-sha256, hmac-sha512, phmac-sha256, and hmac-sha512. The maximum size of the key file is 4096 bytes. + + + The fourth field, if present, is a comma-delimited list of options or a - to specify none. The following options are +@@ -101,7 +101,7 @@ + + + +- ++ + + + The algorithm used for integrity checking. The default is crc32c. Must match option used during format. +diff --git a/src/integritysetup/integrity-util.c b/src/integritysetup/integrity-util.c +index 934e97fa5e..c3bfd636ec 100644 +--- a/src/integritysetup/integrity-util.c ++++ b/src/integritysetup/integrity-util.c +@@ -7,7 +7,7 @@ + #include "percent-util.h" + + static int supported_integrity_algorithm(char *user_supplied) { +- if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256", "hmac-sha512")) ++ if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256", "hmac-sha512", "phmac-sha256", "phmac-sha512")) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported integrity algorithm (%s)", user_supplied); + return 0; + } +diff --git a/src/integritysetup/integrity-util.h b/src/integritysetup/integrity-util.h +index f701b59273..4225834b9b 100644 +--- a/src/integritysetup/integrity-util.h ++++ b/src/integritysetup/integrity-util.h +@@ -16,4 +16,6 @@ int parse_integrity_options( + + #define DM_HMAC_256 "hmac(sha256)" + #define DM_HMAC_512 "hmac(sha512)" ++#define DM_PHMAC_256 "phmac(sha256)" ++#define DM_PHMAC_512 "phmac(sha512)" + #define DM_MAX_KEY_SIZE 4096 /* Maximum size of key allowed for dm-integrity */ +diff --git a/src/integritysetup/integritysetup.c b/src/integritysetup/integritysetup.c +index 674131ed54..fd8a2db9d4 100644 +--- a/src/integritysetup/integritysetup.c ++++ b/src/integritysetup/integritysetup.c +@@ -82,6 +82,10 @@ static const char *integrity_algorithm_select(const void *key_file_buf) { + return DM_HMAC_256; + if (streq("hmac-sha512", arg_integrity_algorithm)) + return DM_HMAC_512; ++ if (streq("phmac-sha256", arg_integrity_algorithm)) ++ return DM_PHMAC_256; ++ if (streq("phmac-sha512", arg_integrity_algorithm)) ++ return DM_PHMAC_512; + return arg_integrity_algorithm; + } else if (key_file_buf) + return DM_HMAC_256; diff --git a/SOURCES/1328-manager-fix-scope-for-environment-generators.patch b/SOURCES/1328-manager-fix-scope-for-environment-generators.patch new file mode 100644 index 0000000..c8a3cf1 --- /dev/null +++ b/SOURCES/1328-manager-fix-scope-for-environment-generators.patch @@ -0,0 +1,27 @@ +From db8eba6c0d1d34086173657cfcd72737d94e8e20 Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Wed, 15 Mar 2023 10:20:59 +0100 +Subject: [PATCH] manager: fix scope for environment generators + +fixes regression introduced by 4870133bfa + +(cherry picked from commit 361cacf49e8fd6b0fc983f0ee507c1d22fa00103) + +Resolves: RHEL-159230 +--- + src/core/manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index ec5e374f24..79408b18dc 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -3695,7 +3695,7 @@ static int manager_run_environment_generators(Manager *m) { + if (MANAGER_IS_TEST_RUN(m) && !(m->test_run_flags & MANAGER_TEST_RUN_ENV_GENERATORS)) + return 0; + +- paths = env_generator_binary_paths(MANAGER_IS_SYSTEM(m)); ++ paths = env_generator_binary_paths(m->runtime_scope); + if (!paths) + return log_oom(); + diff --git a/SOURCES/1329-core-validate-input-cgroup-path-more-prudently.patch b/SOURCES/1329-core-validate-input-cgroup-path-more-prudently.patch new file mode 100644 index 0000000..c70968c --- /dev/null +++ b/SOURCES/1329-core-validate-input-cgroup-path-more-prudently.patch @@ -0,0 +1,29 @@ +From f7a9f500ea223e8cee700d0acdc3a298fb3e0a58 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-155393 +--- + 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 3f62b30745..16c9680d80 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -666,6 +666,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, diff --git a/SOURCES/1330-nspawn-apply-BindUser-Ephemeral-from-settings-file-o.patch b/SOURCES/1330-nspawn-apply-BindUser-Ephemeral-from-settings-file-o.patch new file mode 100644 index 0000000..ff6adfa --- /dev/null +++ b/SOURCES/1330-nspawn-apply-BindUser-Ephemeral-from-settings-file-o.patch @@ -0,0 +1,55 @@ +From 6615811a8c6a36677a389ada8cd7be10e9756e58 Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 11 Mar 2026 12:15:26 +0000 +Subject: [PATCH] nspawn: apply BindUser/Ephemeral from settings file only if + trusted + +Originally reported on yeswehack.com as: +YWH-PGM9780-116 + +Follow-up for 2f8930449079403b26c9164b8eeac78d5af2c8df +Follow-up for a2f577fca0be79b23f61f033229b64884e7d840a + +(cherry picked from commit 61bceb1bff4b1f9c126b18dc971ca3e6d8c71c40) + +Resolves: RHEL-163871 +--- + src/nspawn/nspawn.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index db45968cd3..39d036ef7e 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -4304,8 +4304,13 @@ static int merge_settings(Settings *settings, const char *path) { + } + + if ((arg_settings_mask & SETTING_EPHEMERAL) == 0 && +- settings->ephemeral >= 0) +- arg_ephemeral = settings->ephemeral; ++ settings->ephemeral >= 0) { ++ ++ if (!arg_settings_trusted) ++ log_warning("Ignoring ephemeral setting, file %s is not trusted.", path); ++ else ++ arg_ephemeral = settings->ephemeral; ++ } + + if ((arg_settings_mask & SETTING_DIRECTORY) == 0 && + settings->root) { +@@ -4473,8 +4478,13 @@ static int merge_settings(Settings *settings, const char *path) { + } + + if ((arg_settings_mask & SETTING_BIND_USER) == 0 && +- !strv_isempty(settings->bind_user)) +- strv_free_and_replace(arg_bind_user, settings->bind_user); ++ !strv_isempty(settings->bind_user)) { ++ ++ if (!arg_settings_trusted) ++ log_warning("Ignoring bind user setting, file %s is not trusted.", path); ++ else ++ strv_free_and_replace(arg_bind_user, settings->bind_user); ++ } + + if ((arg_settings_mask & SETTING_NOTIFY_READY) == 0 && + settings->notify_ready >= 0) diff --git a/SOURCES/1331-nspawn-normalize-pivot_root-paths.patch b/SOURCES/1331-nspawn-normalize-pivot_root-paths.patch new file mode 100644 index 0000000..ac0b8c0 --- /dev/null +++ b/SOURCES/1331-nspawn-normalize-pivot_root-paths.patch @@ -0,0 +1,32 @@ +From cfb234e332fe820ef843fb817598ebbbdffdd05f 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-163871 +--- + 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 a54f1464ba..af96d2d1d7 100644 +--- a/src/nspawn/nspawn-mount.c ++++ b/src/nspawn/nspawn-mount.c +@@ -1244,7 +1244,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/SOURCES/1332-core-service-do-not-propagate-reload-for-combined-RE.patch b/SOURCES/1332-core-service-do-not-propagate-reload-for-combined-RE.patch new file mode 100644 index 0000000..e3fcc60 --- /dev/null +++ b/SOURCES/1332-core-service-do-not-propagate-reload-for-combined-RE.patch @@ -0,0 +1,81 @@ +From 3fe4b84a1c363e187be6fc30a19fbf2e66471473 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Wed, 26 Feb 2025 15:02:58 +0100 +Subject: [PATCH] core/service: do not propagate reload for combined + RELOADING=1 + READY=1 when notify-reload + +Follow-up for 3bd28bf721dc70722ff1c675026ed0b44ad968a3 + +SERVICE_RELOAD_SIGNAL state can only be reached via explicit reload jobs, +and we have a clear distinction between that and plain RELOADING=1 +notifications, the latter of which is issued by clients doing reload +outside of our job engine. I.e. upon SERVICE_RELOAD_SIGNAL + RELOADING=1 +we don't propagate reload jobs again, since that's done during transaction +construction stage already. The handling of combined RELOADING=1 + READY=1 +so far is bogus however, as it tries to propagate duplicate reload jobs. +Amend this by following the logic for standalone RELOADING=1. + +(cherry picked from commit c337a1301f2de4105fc8023e45db20238c6a895a) + +Resolves: RHEL-108575 +--- + src/core/service.c | 39 ++++++++++++++++++++++----------------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 9c938aee91..53f40b2d78 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -4218,7 +4218,28 @@ static void service_notify_message( + + s->notify_state = NOTIFY_READY; + +- /* Type=notify services inform us about completed initialization with READY=1 */ ++ /* Combined RELOADING=1 and READY=1? Then this is indication that the service started and ++ * immediately finished reloading. */ ++ if (strv_contains(tags, "RELOADING=1")) { ++ if (s->state == SERVICE_RELOAD_SIGNAL && ++ monotonic_usec != USEC_INFINITY && ++ monotonic_usec >= s->reload_begin_usec) ++ /* Valid Type=notify-reload protocol? Then we're all good. */ ++ service_enter_running(s, SERVICE_SUCCESS); ++ ++ else if (s->state == SERVICE_RUNNING) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ ++ /* Propagate a reload explicitly for plain RELOADING=1 (semantically equivalent to ++ * service_enter_reload_by_notify() call in below) */ ++ r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error); ++ if (r < 0) ++ log_unit_warning(UNIT(s), "Failed to schedule propagation of reload, ignoring: %s", ++ bus_error_message(&error, r)); ++ } ++ } ++ ++ /* Type=notify(-reload) services inform us about completed initialization with READY=1 */ + if (IN_SET(s->type, SERVICE_NOTIFY, SERVICE_NOTIFY_RELOAD) && + s->state == SERVICE_START) + service_enter_start_post(s); +@@ -4227,22 +4248,6 @@ static void service_notify_message( + if (s->state == SERVICE_RELOAD_NOTIFY) + service_enter_running(s, SERVICE_SUCCESS); + +- /* Combined RELOADING=1 and READY=1? Then this is indication that the service started and +- * immediately finished reloading. */ +- if (s->state == SERVICE_RELOAD_SIGNAL && +- strv_contains(tags, "RELOADING=1") && +- monotonic_usec != USEC_INFINITY && +- monotonic_usec >= s->reload_begin_usec) { +- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- +- /* Propagate a reload explicitly */ +- r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error); +- if (r < 0) +- log_unit_warning(UNIT(s), "Failed to schedule propagation of reload, ignoring: %s", bus_error_message(&error, r)); +- +- service_enter_running(s, SERVICE_SUCCESS); +- } +- + notify_dbus = true; + + } else if (strv_contains(tags, "RELOADING=1")) { diff --git a/SOURCES/1333-udev-check-for-invalid-chars-in-various-fields-recei.patch b/SOURCES/1333-udev-check-for-invalid-chars-in-various-fields-recei.patch new file mode 100644 index 0000000..70b6432 --- /dev/null +++ b/SOURCES/1333-udev-check-for-invalid-chars-in-various-fields-recei.patch @@ -0,0 +1,110 @@ +From 967b7954b78bc59e0247e908ea74b19da7112b39 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-163877 +--- + src/udev/dmi_memory_id/dmi_memory_id.c | 3 ++- + src/udev/scsi_id/scsi_id.c | 5 +++-- + src/udev/udev-builtin-net_id.c | 7 ++++++- + src/udev/v4l_id/v4l_id.c | 5 ++++- + 4 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/udev/dmi_memory_id/dmi_memory_id.c b/src/udev/dmi_memory_id/dmi_memory_id.c +index 1345289219..d833a5989d 100644 +--- a/src/udev/dmi_memory_id/dmi_memory_id.c ++++ b/src/udev/dmi_memory_id/dmi_memory_id.c +@@ -50,6 +50,7 @@ + #include "string-util.h" + #include "udev-util.h" + #include "unaligned.h" ++#include "utf8.h" + #include "version.h" + + #define SUPPORTED_SMBIOS_VER 0x030300 +@@ -185,7 +186,7 @@ static void dmi_memory_device_string( + + str = strdupa_safe(dmi_string(h, s)); + str = strstrip(str); +- if (!isempty(str)) ++ if (!isempty(str) && utf8_is_valid(str) && !string_has_cc(str, /* ok= */ NULL)) + printf("MEMORY_DEVICE_%u_%s=%s\n", slot_num, attr_suffix, str); + } + +diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c +index 364d567705..2a489f4e38 100644 +--- a/src/udev/scsi_id/scsi_id.c ++++ b/src/udev/scsi_id/scsi_id.c +@@ -26,6 +26,7 @@ + #include "strv.h" + #include "strxcpyx.h" + #include "udev-util.h" ++#include "utf8.h" + #include "version.h" + + static const struct option options[] = { +@@ -441,8 +442,8 @@ static int scsi_id(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 e1895a38c0..6bb6465832 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -39,6 +39,7 @@ + #include "strv.h" + #include "strxcpyx.h" + #include "udev-builtin.h" ++#include "utf8.h" + + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) +@@ -1188,9 +1189,13 @@ static int get_link_info(sd_device *dev, LinkInfo *info) { + return r; + + r = device_get_sysattr_value_filtered(dev, "phys_port_name", &info->phys_port_name); +- if (r >= 0) ++ if (r >= 0) { ++ if (!utf8_is_valid(info->phys_port_name) || string_has_cc(info->phys_port_name, /* ok= */ NULL)) ++ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid phys_port_name"); ++ + /* Check if phys_port_name indicates virtual device representor */ + (void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id); ++ } + + r = device_get_sysattr_value_filtered(dev, "address", &s); + if (r < 0 && r != -ENOENT) +diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c +index c2312c7909..ae8459c456 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[]) { +@@ -66,7 +68,8 @@ int main(int argc, char *argv[]) { + if (ioctl(fd, VIDIOC_QUERYCAP, &v2cap) == 0) { + int capabilities; + 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_DEVICE_CAPS) + capabilities = v2cap.device_caps; diff --git a/SOURCES/1334-udev-fix-review-mixup.patch b/SOURCES/1334-udev-fix-review-mixup.patch new file mode 100644 index 0000000..e53b3ce --- /dev/null +++ b/SOURCES/1334-udev-fix-review-mixup.patch @@ -0,0 +1,32 @@ +From 320ca2d881198cab52b4c6dd073967f2d4b2e919 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-163877 +--- + 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 2a489f4e38..71c5534851 100644 +--- a/src/udev/scsi_id/scsi_id.c ++++ b/src/udev/scsi_id/scsi_id.c +@@ -443,7 +443,7 @@ static int scsi_id(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/SOURCES/1335-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch b/SOURCES/1335-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch new file mode 100644 index 0000000..dad2bcc --- /dev/null +++ b/SOURCES/1335-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch @@ -0,0 +1,52 @@ +From a7e7bf455cb22e95c4487c91cd040e3c27fa64e7 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-163877 +--- + 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 71c5534851..2f2a07891f 100644 +--- a/src/udev/scsi_id/scsi_id.c ++++ b/src/udev/scsi_id/scsi_id.c +@@ -389,6 +389,10 @@ static int set_inq_values(struct scsi_id_device *dev_scsi, const char *path) { + 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. +@@ -432,17 +436,17 @@ static int scsi_id(char *maj_min_dev) { + udev_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/SOURCES/1336-core-cleanup-unit-s-dropin-directories-from-global-c.patch b/SOURCES/1336-core-cleanup-unit-s-dropin-directories-from-global-c.patch new file mode 100644 index 0000000..d6ba4a7 --- /dev/null +++ b/SOURCES/1336-core-cleanup-unit-s-dropin-directories-from-global-c.patch @@ -0,0 +1,42 @@ +From 4843d4f679bb4dd70f15ce49f0786e80bb821e28 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 25 Feb 2026 19:45:55 +0100 +Subject: [PATCH] core: cleanup unit's dropin directories from global cache + +When user creates dropin files via API (e.g. systemctl set-property ...) +we put the dropin directory path into unit_path_cache. Drop those +directories from the cache in unit_free() and prevent memory leak. + +Follow-up for fce94c5c563b8f6ede2b8f7f283d2d2faff4e062. + +(cherry picked from commit 0c98e432d1def1e8428dbead50dc629ed0645366) + +Resolves: RHEL-127425 +--- + src/core/unit.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 7f321c911d..790f4023a2 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -603,6 +603,8 @@ static void unit_remove_transient(Unit *u) { + if (!u->transient) + return; + ++ const char *dropin_directory = strjoina(u->id, ".d"); ++ + STRV_FOREACH(i, u->dropin_paths) { + _cleanup_free_ char *p = NULL, *pp = NULL; + +@@ -616,6 +618,10 @@ static void unit_remove_transient(Unit *u) { + if (!path_equal(u->manager->lookup_paths.transient, pp)) + continue; + ++ /* Drop the transient drop-in directory also from unit path cache. */ ++ if (path_equal(last_path_component(p), dropin_directory)) ++ free(set_remove(u->manager->unit_path_cache, p)); ++ + (void) unlink(*i); + (void) rmdir(p); + } diff --git a/SOURCES/1337-udev-allow-persistent-storage-rules-for-rbd-devices.patch b/SOURCES/1337-udev-allow-persistent-storage-rules-for-rbd-devices.patch new file mode 100644 index 0000000..ae0bb5c --- /dev/null +++ b/SOURCES/1337-udev-allow-persistent-storage-rules-for-rbd-devices.patch @@ -0,0 +1,41 @@ +From b7156edf92d815ad3bf84fbcaaa7a4a94a648999 Mon Sep 17 00:00:00 2001 +From: Peter Rajnoha +Date: Thu, 5 Sep 2024 12:31:20 +0200 +Subject: [PATCH] udev: allow persistent storage rules for rbd devices + +The RADOS Block Device (rbd) can be used as any other block device with +further layers on top of it, hence allow the common persistent storage +rules to apply, including watching for changes. + +(cherry picked from commit cbe65d38cf0a2e55cdba75871de108bc505a7095) + +Resolves: RHEL-3631 +--- + rules.d/60-block.rules | 2 +- + rules.d/60-persistent-storage.rules | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/rules.d/60-block.rules b/rules.d/60-block.rules +index 3134ab995e..13f88e92c8 100644 +--- a/rules.d/60-block.rules ++++ b/rules.d/60-block.rules +@@ -9,5 +9,5 @@ ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", + + # watch metadata changes, caused by tools closing the device node which was opened for writing + ACTION!="remove", SUBSYSTEM=="block", \ +- KERNEL=="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*", \ ++ KERNEL=="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*|rbd*", \ + OPTIONS+="watch" +diff --git a/rules.d/60-persistent-storage.rules b/rules.d/60-persistent-storage.rules +index 10b347e191..3aa365bec4 100644 +--- a/rules.d/60-persistent-storage.rules ++++ b/rules.d/60-persistent-storage.rules +@@ -7,7 +7,7 @@ ACTION=="remove", GOTO="persistent_storage_end" + ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_end" + + SUBSYSTEM!="block|ubi", GOTO="persistent_storage_end" +-KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*", GOTO="persistent_storage_end" ++KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*|rbd*", GOTO="persistent_storage_end" + + # ignore partitions that span the entire disk + TEST=="whole_disk", GOTO="persistent_storage_end" diff --git a/SOURCES/1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch b/SOURCES/1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch new file mode 100644 index 0000000..5478e86 --- /dev/null +++ b/SOURCES/1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch @@ -0,0 +1,55 @@ +From 1aaebe972b912e1f2ef3b874edb22e47f7def5b9 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 4 May 2026 09:30:17 +0200 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-9.9 + +rhel-only: policy + +Resolves: RHEL-25518 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/shared/netif-naming-scheme.c | 1 + + src/shared/netif-naming-scheme.h | 1 + + 3 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index c6ee7b4b6e..be7197d62d 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -533,6 +533,12 @@ + PCI slot number is now read from firmware_node/sun sysfs file. + + ++ ++ rhel-9.9 ++ ++ Same as naming scheme rhel-9.8. ++ ++ + + + By default rhel-9.0 is used. +diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c +index 4ed866491e..5edc50069d 100644 +--- a/src/shared/netif-naming-scheme.c ++++ b/src/shared/netif-naming-scheme.c +@@ -48,6 +48,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-9.6", NAMING_RHEL_9_6 }, + { "rhel-9.7", NAMING_RHEL_9_7 }, + { "rhel-9.8", NAMING_RHEL_9_8 }, ++ { "rhel-9.9", NAMING_RHEL_9_9 }, + /* … add more schemes here, as the logic to name devices is updated … */ + + EXTRA_NET_NAMING_MAP +diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h +index c16476522a..6bb8db920e 100644 +--- a/src/shared/netif-naming-scheme.h ++++ b/src/shared/netif-naming-scheme.h +@@ -78,6 +78,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_9_6 = NAMING_RHEL_9_5, + NAMING_RHEL_9_7 = NAMING_RHEL_9_5, + NAMING_RHEL_9_8 = NAMING_RHEL_9_5 | NAMING_FIRMWARE_NODE_SUN, ++ NAMING_RHEL_9_9 = NAMING_RHEL_9_8, + + EXTRA_NET_NAMING_SCHEMES + diff --git a/SOURCES/1339-fstab-generator-support-swap-on-network-block-device.patch b/SOURCES/1339-fstab-generator-support-swap-on-network-block-device.patch new file mode 100644 index 0000000..b2e0e9a --- /dev/null +++ b/SOURCES/1339-fstab-generator-support-swap-on-network-block-device.patch @@ -0,0 +1,322 @@ +From e5e4bfa6dcdc2502e57c813ea0d0a72ee37fb337 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 7 Apr 2026 11:16:42 +0200 +Subject: [PATCH] fstab-generator: support swap on network block devices + +Teach swap units to support the _netdev option as well, which should +make swaps on iSCSI possible. This mirrors the logic we already have for +regular mounts in both the fstab-generator and the core +(mount.c/swap.c). + +Co-developed-by: Claude Opus 4.6 +(cherry picked from commit 3d5bd67a2259e7a4edc27476d4cae049653c4414) + +Resolves: RHEL-166187 +--- + man/systemd.swap.xml | 28 +++++++++-- + src/core/swap.c | 46 ++++++++++++++++--- + src/fstab-generator/fstab-generator.c | 16 +++++-- + src/shared/generator.c | 2 +- + .../systemd-remount-fs.service | 0 + .../sysroot.mount | 0 + .../50-netdev-dependencies.conf | 5 ++ + .../dev-sdx1.swap | 10 ++++ + .../systemd-remount-fs.service | 0 + .../remote-fs.target.requires/dev-sdx1.swap | 1 + + .../50-netdev-dependencies.conf | 5 ++ + .../dev-sdx1.swap | 10 ++++ + .../sysroot.mount | 0 + .../remote-fs.target.requires/dev-sdx1.swap | 1 + + .../test-21-swap-netdev.fstab.input | 1 + + 15 files changed, 111 insertions(+), 14 deletions(-) + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container.sysroot/local-fs.target.wants/systemd-remount-fs.service + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container/initrd-usr-fs.target.requires/sysroot.mount + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service + create mode 120000 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount + create mode 120000 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap + create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.input + +diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml +index 8287382eb6..6af8a31021 100644 +--- a/man/systemd.swap.xml ++++ b/man/systemd.swap.xml +@@ -90,9 +90,15 @@ + The following dependencies are added unless DefaultDependencies=no is set: + + +- Swap units automatically acquire a Conflicts= and a ++ Local swap units automatically acquire a Conflicts= and a + Before= dependency on umount.target so that they are deactivated at + shutdown as well as a Before=swap.target dependency. ++ ++ Network swap units (those with in their options) automatically acquire ++ After= dependencies on remote-fs-pre.target and ++ network.target, plus After= and Wants= dependencies ++ on network-online.target, and a Before= dependency on ++ remote-fs.target instead of swap.target. + + + +@@ -124,7 +130,8 @@ + + With , the swap unit + will not be added as a dependency for +- swap.target. This means that it will not ++ swap.target (or remote-fs.target for network swap devices, ++ see below). This means that it will not + be activated automatically during boot, unless it is pulled in + by some other unit. The option has the + opposite meaning and is the default. +@@ -136,8 +143,8 @@ + + With , the swap unit + will be only wanted, not required by +- swap.target. This means that the boot +- will continue even if this swap device is not activated ++ swap.target (or remote-fs.target for network swap ++ devices). This means that the boot will continue even if this swap device is not activated + successfully. + + +@@ -161,6 +168,19 @@ + in systemd.mount5. + + ++ ++ ++ ++ ++ Marks this swap device as requiring network access. This is useful for swap on ++ network block devices (e.g. iSCSI). ++ ++ Network swap units are ordered between remote-fs-pre.target and ++ remote-fs.target, instead of being ordered before ++ swap.target. They also pull in network-online.target and ++ are ordered after it and network.target. ++ ++ + + + +diff --git a/src/core/swap.c b/src/core/swap.c +index 5c83c4780f..10743d4b9d 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -253,6 +253,7 @@ static int swap_add_device_dependencies(Swap *s) { + } + + static int swap_add_default_dependencies(Swap *s) { ++ SwapParameters *p; + int r; + + assert(s); +@@ -266,13 +267,46 @@ static int swap_add_default_dependencies(Swap *s) { + if (detect_container() > 0) + return 0; + +- /* swap units generated for the swap dev links are missing the +- * ordering dep against the swap target. */ +- r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, true, UNIT_DEPENDENCY_DEFAULT); +- if (r < 0) +- return r; ++ p = swap_get_parameters(s); ++ ++ if (p && fstab_test_option(p->options, "_netdev\0")) { ++ /* Network swap devices (those with _netdev in options) are routed through ++ * remote-fs.target instead of swap.target, mirroring how network mounts use ++ * remote-fs.target instead of local-fs.target. This avoids an ordering cycle: ++ * swap.target is pulled in at sysinit.target time, but network-online.target ++ * only comes after basic.target which is after sysinit.target. */ ++ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOTE_FS_PRE_TARGET, ++ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT); ++ if (r < 0) ++ return r; ++ ++ r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, ++ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT); ++ if (r < 0) ++ return r; ++ ++ /* Pull in and order after network-online.target, analogous to ++ * mount_add_default_network_dependencies() for network mounts. */ ++ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_NETWORK_TARGET, ++ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT); ++ if (r < 0) ++ return r; ++ ++ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, ++ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT); ++ if (r < 0) ++ return r; ++ } else { ++ /* swap units generated for the swap dev links are missing the ++ * ordering dep against the swap target. */ ++ r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, ++ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT); ++ if (r < 0) ++ return r; ++ } + +- return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, UNIT_DEPENDENCY_DEFAULT); ++ return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, ++ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT); + } + + static int swap_verify(Swap *s) { +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index 28677a2f39..7b417dd2d1 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -208,6 +208,7 @@ static int add_swap( + + _cleanup_free_ char *name = NULL; + _cleanup_fclose_ FILE *f = NULL; ++ bool is_network; + int r; + + assert(what); +@@ -227,10 +228,12 @@ static int add_swap( + return true; + } + +- log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s", ++ is_network = fstab_test_option(options, "_netdev\0"); ++ ++ log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s netdev=%s", + what, + yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS), yes_no(flags & MOUNT_PCRFS), +- yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL)); ++ yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL), yes_no(is_network)); + + r = unit_name_from_path(what, ".swap", &name); + if (r < 0) +@@ -271,6 +274,12 @@ static int add_swap( + if (r < 0) + return r; + ++ if (is_network) { ++ r = generator_write_device_deps(arg_dest, what, /* where= */ NULL, options); ++ if (r < 0) ++ return r; ++ } ++ + if (flags & MOUNT_MAKEFS) { + r = generator_hook_up_mkswap(arg_dest, what); + if (r < 0) +@@ -284,7 +293,8 @@ static int add_swap( + log_warning("%s: measuring swap devices is currently unsupported.", what); + + if (!(flags & MOUNT_NOAUTO)) { +- r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET, ++ const char *target = is_network ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_SWAP_TARGET; ++ r = generator_add_symlink(arg_dest, target, + (flags & MOUNT_NOFAIL) ? "wants" : "requires", name); + if (r < 0) + return r; +diff --git a/src/shared/generator.c b/src/shared/generator.c +index a688ba446c..5dc103400b 100644 +--- a/src/shared/generator.c ++++ b/src/shared/generator.c +@@ -428,7 +428,7 @@ int generator_write_device_deps( + _cleanup_free_ char *node = NULL, *unit = NULL; + int r; + +- if (fstab_is_extrinsic(where, opts)) ++ if (where && fstab_is_extrinsic(where, opts)) + return 0; + + if (!fstab_test_option(opts, "_netdev\0")) +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container.sysroot/local-fs.target.wants/systemd-remount-fs.service b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container.sysroot/local-fs.target.wants/systemd-remount-fs.service +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container/initrd-usr-fs.target.requires/sysroot.mount +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf +new file mode 100644 +index 0000000000..33d814c275 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf +@@ -0,0 +1,5 @@ ++# Automatically generated by systemd-fstab-generator ++ ++[Unit] ++After=network-online.target network.target ++Wants=network-online.target +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap +new file mode 100644 +index 0000000000..32f276c9e1 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap +@@ -0,0 +1,10 @@ ++# Automatically generated by systemd-fstab-generator ++ ++[Unit] ++Documentation=man:fstab(5) man:systemd-fstab-generator(8) ++SourcePath=/etc/fstab ++After=blockdev@dev-sdx1.target ++ ++[Swap] ++What=/dev/sdx1 ++Options=_netdev +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap +new file mode 120000 +index 0000000000..00f0c5ce66 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap +@@ -0,0 +1 @@ ++../dev-sdx1.swap +\ No newline at end of file +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf +new file mode 100644 +index 0000000000..33d814c275 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf +@@ -0,0 +1,5 @@ ++# Automatically generated by systemd-fstab-generator ++ ++[Unit] ++After=network-online.target network.target ++Wants=network-online.target +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap +new file mode 100644 +index 0000000000..32f276c9e1 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap +@@ -0,0 +1,10 @@ ++# Automatically generated by systemd-fstab-generator ++ ++[Unit] ++Documentation=man:fstab(5) man:systemd-fstab-generator(8) ++SourcePath=/etc/fstab ++After=blockdev@dev-sdx1.target ++ ++[Swap] ++What=/dev/sdx1 ++Options=_netdev +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap +new file mode 120000 +index 0000000000..00f0c5ce66 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap +@@ -0,0 +1 @@ ++../dev-sdx1.swap +\ No newline at end of file +diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.input b/test/test-fstab-generator/test-21-swap-netdev.fstab.input +new file mode 100644 +index 0000000000..5f719a4202 +--- /dev/null ++++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.input +@@ -0,0 +1 @@ ++/dev/sdx1 none swap _netdev 0 0 diff --git a/SOURCES/1340-core-increment-start-limit-counter-only-when-we-can-.patch b/SOURCES/1340-core-increment-start-limit-counter-only-when-we-can-.patch new file mode 100644 index 0000000..a7a8fce --- /dev/null +++ b/SOURCES/1340-core-increment-start-limit-counter-only-when-we-can-.patch @@ -0,0 +1,460 @@ +From 4060cdad388b0ae658f2024633b842a46c37962e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 20 Oct 2025 19:40:28 +0900 +Subject: [PATCH] core: increment start limit counter only when we can start + the unit + +Otherwise, e.g. requesting to start a unit that is under stopping may +enter the failed state. + +This makes +- rename .can_start() -> .test_startable(), and make it allow to return + boolean and refuse to start units when it returns false, +- refuse earlier to start units that are in the deactivating state, so + several redundant conditions in .start() can be dropped, +- move checks for unit states mapped to UNIT_ACTIVATING from .start() to + .test_startable(). + +Fixes #39247. + +(cherry picked from commit 8eefd0f4debc0bcfeea89dd39c43e3318f3f7ae7) + +Resolves: RHEL-164539 +--- + src/core/automount.c | 6 ++-- + src/core/mount.c | 25 +++++---------- + src/core/path.c | 6 ++-- + src/core/service.c | 24 ++++++--------- + src/core/socket.c | 32 ++++++-------------- + src/core/swap.c | 23 +++++--------- + src/core/timer.c | 6 ++-- + src/core/unit.c | 11 ++++--- + src/core/unit.h | 4 +-- + test/units/TEST-07-PID1.start-limit.sh | 42 ++++++++++++++++++++++++++ + 10 files changed, 93 insertions(+), 86 deletions(-) + create mode 100755 test/units/TEST-07-PID1.start-limit.sh + +diff --git a/src/core/automount.c b/src/core/automount.c +index a44b8e878d..ae8399d1af 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -1084,7 +1084,7 @@ static bool automount_supported(void) { + return supported; + } + +-static int automount_can_start(Unit *u) { ++static int automount_test_startable(Unit *u) { + Automount *a = AUTOMOUNT(u); + int r; + +@@ -1096,7 +1096,7 @@ static int automount_can_start(Unit *u) { + return r; + } + +- return 1; ++ return true; + } + + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { +@@ -1162,5 +1162,5 @@ const UnitVTable automount_vtable = { + }, + }, + +- .can_start = automount_can_start, ++ .test_startable = automount_test_startable, + }; +diff --git a/src/core/mount.c b/src/core/mount.c +index be6fbf4cc4..5789a253cd 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1212,21 +1212,6 @@ static int mount_start(Unit *u) { + Mount *m = MOUNT(u); + int r; + +- assert(m); +- +- /* We cannot fulfill this request right now, try again later +- * please! */ +- if (IN_SET(m->state, +- MOUNT_UNMOUNTING, +- MOUNT_UNMOUNTING_SIGTERM, +- MOUNT_UNMOUNTING_SIGKILL, +- MOUNT_CLEANING)) +- return -EAGAIN; +- +- /* Already on it! */ +- if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE)) +- return 0; +- + assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED)); + + r = unit_acquire_invocation_id(u); +@@ -2214,19 +2199,23 @@ static int mount_can_clean(Unit *u, ExecCleanMask *ret) { + return exec_context_get_clean_mask(&m->exec_context, ret); + } + +-static int mount_can_start(Unit *u) { ++static int mount_test_startable(Unit *u) { + Mount *m = MOUNT(u); + int r; + + assert(m); + ++ /* It is already being started. */ ++ if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE)) ++ return false; ++ + r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); + return r; + } + +- return 1; ++ return true; + } + + char* mount_get_where_escaped(const Mount *m) { +@@ -2337,5 +2326,5 @@ const UnitVTable mount_vtable = { + }, + }, + +- .can_start = mount_can_start, ++ .test_startable = mount_test_startable, + }; +diff --git a/src/core/path.c b/src/core/path.c +index 3a46e44928..6f850244f1 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -846,7 +846,7 @@ static void path_reset_failed(Unit *u) { + p->result = PATH_SUCCESS; + } + +-static int path_can_start(Unit *u) { ++static int path_test_startable(Unit *u) { + Path *p = PATH(u); + int r; + +@@ -858,7 +858,7 @@ static int path_can_start(Unit *u) { + return r; + } + +- return 1; ++ return true; + } + + static void activation_details_path_done(ActivationDetails *details) { +@@ -1000,7 +1000,7 @@ const UnitVTable path_vtable = { + + .bus_set_property = bus_path_set_property, + +- .can_start = path_can_start, ++ .test_startable = path_test_startable, + }; + + const ActivationDetailsVTable activation_details_path_vtable = { +diff --git a/src/core/service.c b/src/core/service.c +index 53f40b2d78..e152fb6227 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2557,17 +2557,6 @@ static int service_start(Unit *u) { + + assert(s); + +- /* We cannot fulfill this request right now, try again later +- * please! */ +- if (IN_SET(s->state, +- SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, +- SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL, SERVICE_CLEANING)) +- return -EAGAIN; +- +- /* Already on it! */ +- if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST)) +- return 0; +- + /* A service that will be restarted must be stopped first to + * trigger BindsTo and/or OnFailure dependencies. If a user + * does not want to wait for the holdoff time to elapse, the +@@ -4707,12 +4696,19 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) { + return NULL; + } + +-static int service_can_start(Unit *u) { ++static int service_test_startable(Unit *u) { + Service *s = SERVICE(u); + int r; + + assert(s); + ++ /* First check the state, and do not increment start limit counter if the service cannot start due to ++ * that e.g. it is already being started. Note, the service states mapped to UNIT_ACTIVE, ++ * UNIT_RELOADING, UNIT_DEACTIVATING, UNIT_MAINTENANCE, and UNIT_REFRESHING are already filtered in ++ * unit_start(). Hence, here we only need to check states that mapped to UNIT_ACTIVATING. */ ++ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST)) ++ return false; ++ + /* Make sure we don't enter a busy loop of some kind. */ + r = unit_test_start_limit(u); + if (r < 0) { +@@ -4720,7 +4716,7 @@ static int service_can_start(Unit *u) { + return r; + } + +- return 1; ++ return true; + } + + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { +@@ -4896,5 +4892,5 @@ const UnitVTable service_vtable = { + .finished_job = service_finished_job, + }, + +- .can_start = service_can_start, ++ .test_startable = service_test_startable, + }; +diff --git a/src/core/socket.c b/src/core/socket.c +index 7abae70255..103b399ab8 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2460,25 +2460,6 @@ static int socket_start(Unit *u) { + + assert(s); + +- /* We cannot fulfill this request right now, try again later +- * please! */ +- if (IN_SET(s->state, +- SOCKET_STOP_PRE, +- SOCKET_STOP_PRE_SIGKILL, +- SOCKET_STOP_PRE_SIGTERM, +- SOCKET_STOP_POST, +- SOCKET_FINAL_SIGTERM, +- SOCKET_FINAL_SIGKILL, +- SOCKET_CLEANING)) +- return -EAGAIN; +- +- /* Already on it! */ +- if (IN_SET(s->state, +- SOCKET_START_PRE, +- SOCKET_START_CHOWN, +- SOCKET_START_POST)) +- return 0; +- + /* Cannot run this without the service being around */ + if (UNIT_ISSET(s->service)) { + Service *service; +@@ -3392,19 +3373,26 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) { + return exec_context_get_clean_mask(&s->exec_context, ret); + } + +-static int socket_can_start(Unit *u) { ++static int socket_test_startable(Unit *u) { + Socket *s = SOCKET(u); + int r; + + assert(s); + ++ /* It is already being started. */ ++ if (IN_SET(s->state, ++ SOCKET_START_PRE, ++ SOCKET_START_CHOWN, ++ SOCKET_START_POST)) ++ return false; ++ + r = unit_test_start_limit(u); + if (r < 0) { + socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); + return r; + } + +- return 1; ++ return true; + } + + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { +@@ -3534,5 +3522,5 @@ const UnitVTable socket_vtable = { + }, + }, + +- .can_start = socket_can_start, ++ .test_startable = socket_test_startable, + }; +diff --git a/src/core/swap.c b/src/core/swap.c +index 10743d4b9d..458c935b0c 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -933,19 +933,6 @@ static int swap_start(Unit *u) { + int r; + + assert(s); +- +- /* We cannot fulfill this request right now, try again later please! */ +- if (IN_SET(s->state, +- SWAP_DEACTIVATING, +- SWAP_DEACTIVATING_SIGTERM, +- SWAP_DEACTIVATING_SIGKILL, +- SWAP_CLEANING)) +- return -EAGAIN; +- +- /* Already on it! */ +- if (s->state == SWAP_ACTIVATING) +- return 0; +- + assert(IN_SET(s->state, SWAP_DEAD, SWAP_FAILED)); + + if (detect_container() > 0) +@@ -1612,19 +1599,23 @@ static int swap_can_clean(Unit *u, ExecCleanMask *ret) { + return exec_context_get_clean_mask(&s->exec_context, ret); + } + +-static int swap_can_start(Unit *u) { ++static int swap_test_startable(Unit *u) { + Swap *s = SWAP(u); + int r; + + assert(s); + ++ /* It is already being started. */ ++ if (s->state == SWAP_ACTIVATING) ++ return false; ++ + r = unit_test_start_limit(u); + if (r < 0) { + swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); + return r; + } + +- return 1; ++ return true; + } + + static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { +@@ -1723,5 +1714,5 @@ const UnitVTable swap_vtable = { + }, + }, + +- .can_start = swap_can_start, ++ .test_startable = swap_test_startable, + }; +diff --git a/src/core/timer.c b/src/core/timer.c +index 8fb79bc0cb..b96e88af90 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -897,7 +897,7 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) { + return 0; + } + +-static int timer_can_start(Unit *u) { ++static int timer_test_startable(Unit *u) { + Timer *t = TIMER(u); + int r; + +@@ -909,7 +909,7 @@ static int timer_can_start(Unit *u) { + return r; + } + +- return 1; ++ return true; + } + + static void activation_details_timer_serialize(ActivationDetails *details, FILE *f) { +@@ -1057,7 +1057,7 @@ const UnitVTable timer_vtable = { + + .bus_set_property = bus_timer_set_property, + +- .can_start = timer_can_start, ++ .test_startable = timer_test_startable, + }; + + const ActivationDetailsVTable activation_details_timer_vtable = { +diff --git a/src/core/unit.c b/src/core/unit.c +index 790f4023a2..0b58d0498b 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1846,7 +1846,7 @@ int unit_start(Unit *u, ActivationDetails *details) { + state = unit_active_state(u); + if (UNIT_IS_ACTIVE_OR_RELOADING(state)) + return -EALREADY; +- if (state == UNIT_MAINTENANCE) ++ if (IN_SET(state, UNIT_DEACTIVATING, UNIT_MAINTENANCE)) + return -EAGAIN; + + /* Units that aren't loaded cannot be started */ +@@ -1889,10 +1889,11 @@ int unit_start(Unit *u, ActivationDetails *details) { + return unit_start(following, details); + } + +- /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ +- if (UNIT_VTABLE(u)->can_start) { +- r = UNIT_VTABLE(u)->can_start(u); +- if (r < 0) ++ /* Check our ability to start early so that ratelimited or already starting/started units don't ++ * cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->test_startable) { ++ r = UNIT_VTABLE(u)->test_startable(u); ++ if (r <= 0) + return r; + } + +diff --git a/src/core/unit.h b/src/core/unit.h +index fdea76458d..acbf74477e 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -751,8 +751,8 @@ typedef struct UnitVTable { + bool (*supported)(void); + + /* If this function is set, it's invoked first as part of starting a unit to allow start rate +- * limiting checks to occur before we do anything else. */ +- int (*can_start)(Unit *u); ++ * limiting checks and unit state checks to occur before we do anything else. */ ++ int (*test_startable)(Unit *u); + + /* The strings to print in status messages */ + UnitStatusMessageFormats status_message_formats; +diff --git a/test/units/TEST-07-PID1.start-limit.sh b/test/units/TEST-07-PID1.start-limit.sh +new file mode 100755 +index 0000000000..f793d32876 +--- /dev/null ++++ b/test/units/TEST-07-PID1.start-limit.sh +@@ -0,0 +1,42 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++set -eux ++set -o pipefail ++ ++# For issue #39247. ++ ++at_exit() { ++ set +e ++ ++ rm -rf /run/systemd/system/systemd-resolved.service.d/ ++ systemctl daemon-reload ++ systemctl restart systemd-resolved.service ++} ++ ++trap at_exit EXIT ++ ++mkdir -p /run/systemd/system/systemd-resolved.service.d/ ++cat >/run/systemd/system/systemd-resolved.service.d/99-start-limit.conf < +Date: Tue, 28 Oct 2025 13:20:58 +0900 +Subject: [PATCH] TEST-07-PID1: wait for systemd-resolved being stopped + +As 'systemctl stop' is called with --no-block, previously systemd-resolved +might not be stopped when 'resolvectl' is called, and the DBus connection +might be closed during the call: +``` +TEST-07-PID1.sh[5643]: + systemctl stop --no-block systemd-resolved.service +TEST-07-PID1.sh[5643]: + resolvectl +TEST-07-PID1.sh[5732]: Failed to get global data: Remote peer disconnected +``` + +Follow-up for 8eefd0f4debc0bcfeea89dd39c43e3318f3f7ae7. +Fixes https://github.com/systemd/systemd/pull/39388#issuecomment-3439277442. + +(cherry picked from commit 6454fde83eef8da7391ad18a1b1a3248402f9214) + +Related: RHEL-164539 +--- + test/units/TEST-07-PID1.start-limit.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/test/units/TEST-07-PID1.start-limit.sh b/test/units/TEST-07-PID1.start-limit.sh +index f793d32876..b512c58ff2 100755 +--- a/test/units/TEST-07-PID1.start-limit.sh ++++ b/test/units/TEST-07-PID1.start-limit.sh +@@ -35,6 +35,9 @@ for i in {1..5}; do + echo "Start #$i" + + systemctl stop --no-block systemd-resolved.service ++ # Wait for systemd-resolved in ExecStart= being stopped. ++ # shellcheck disable=SC2016 ++ timeout 10 bash -c 'until [[ "$(systemctl show --property=MainPID --value systemd-resolved.service)" == 0 ]]; do sleep 0.1; done' + if ! resolvectl; then + journalctl -o short-monotonic --no-hostname --no-pager -u systemd-resolved.service -n 15 + exit 1 diff --git a/SOURCES/1342-test-extend-start-limit-interval.patch b/SOURCES/1342-test-extend-start-limit-interval.patch new file mode 100644 index 0000000..d11fa08 --- /dev/null +++ b/SOURCES/1342-test-extend-start-limit-interval.patch @@ -0,0 +1,40 @@ +From d092520e2c3221e191b46c6c771d54ec51f678dc Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sat, 25 Oct 2025 15:34:44 +0900 +Subject: [PATCH] test: extend start limit interval + +As the modified service requires about ~10 seconds for stopping, the +service never hit the start limit even if we tried to restart the +service more than 5 times. + +This also checks that the service is actually triggered by dbus method +call. + +Follow-up for 8eefd0f4debc0bcfeea89dd39c43e3318f3f7ae7. + +(cherry picked from commit 44b4caad6cc99449bbf705350939fde1ed9b1248) + +Related: RHEL-164539 +--- + test/units/TEST-07-PID1.start-limit.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test/units/TEST-07-PID1.start-limit.sh b/test/units/TEST-07-PID1.start-limit.sh +index b512c58ff2..93447452da 100755 +--- a/test/units/TEST-07-PID1.start-limit.sh ++++ b/test/units/TEST-07-PID1.start-limit.sh +@@ -19,7 +19,7 @@ mkdir -p /run/systemd/system/systemd-resolved.service.d/ + cat >/run/systemd/system/systemd-resolved.service.d/99-start-limit.conf < +Date: Tue, 6 May 2025 11:14:10 +0200 +Subject: [PATCH] man: reword the description of "secure pager" handling + +The existing description was not *wrong*, but it was a bit muddled. Let's +reorder the text to give a short intro and then describe what the options +actually do and the clear "true" and "false" cases first, and then describe +autodetection. + +Related to https://yeswehack.com/vulnerability-center/reports/346802. + +(cherry picked from commit 718dbdb2ca4458cf91711cd9a7de3a972e46658e) + +Related: RHEL-102941 +--- + man/common-variables.xml | 58 ++++++++++++++++++++++++++-------------- + 1 file changed, 38 insertions(+), 20 deletions(-) + +diff --git a/man/common-variables.xml b/man/common-variables.xml +index 0e220b3f9e..d6de5ed059 100644 +--- a/man/common-variables.xml ++++ b/man/common-variables.xml +@@ -144,28 +144,46 @@ + + $SYSTEMD_PAGERSECURE + +- Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if +- false, disabled. If $SYSTEMD_PAGERSECURE is not set at all, secure mode is enabled +- if the effective UID is not the same as the owner of the login session, see +- geteuid2 +- and sd_pid_get_owner_uid3. +- In secure mode, will be set when invoking the pager, and the pager shall +- disable commands that open or create new files or start new subprocesses. When +- $SYSTEMD_PAGERSECURE is not set at all, pagers which are not known to implement +- secure mode will not be used. (Currently only +- less1 +- implements secure mode.) +- +- Note: when commands are invoked with elevated privileges, for example under ++ Common pager commands like less1, in ++ addition to "paging", i.e. scrolling through the output, support opening of or writing to other files ++ and running arbitrary shell commands. When commands are invoked with elevated privileges, for example ++ under sudo8 or + pkexec1, care +- must be taken to ensure that unintended interactive features are not enabled. "Secure" mode for the +- pager may be enabled automatically as describe above. Setting SYSTEMD_PAGERSECURE=0 +- or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note +- that if the $SYSTEMD_PAGER or $PAGER variables are to be +- honoured, $SYSTEMD_PAGERSECURE must be set too. It might be reasonable to completely +- disable the pager using instead. ++ project='die-net'>pkexec1, the ++ pager becomes a security boundary. Care must be taken that only programs with strictly limited ++ functionality are used as pagers, and unintended interactive features like opening or creation of new ++ files or starting of subprocesses are not allowed. "Secure mode" for the pager may be enabled as ++ described below, if the pager supports that (most pagers are not written in a way ++ that takes this into consideration). It is recommended to either explicitly enable "secure mode" or to ++ completely disable the pager using or PAGER=cat when ++ allowing untrusted users to execute commands with elevated privileges. ++ ++ This option takes a boolean argument. When set to true, the "secure mode" of the pager is ++ enabled. In "secure mode", will be set when invoking the pager, which ++ instructs the pager to disable commands that open or create new files or start new subprocesses. ++ Currently only less1 is known ++ to understand this variable and implement "secure mode". ++ ++ When set to false, no limitation is placed on the pager. Setting ++ SYSTEMD_PAGERSECURE=0 or not removing it from the inherited environment may allow ++ the user to invoke arbitrary commands. ++ ++ When $SYSTEMD_PAGERSECURE is not set, systemd tools attempt to automatically ++ figure out if "secure mode" should be enabled and whether the pager supports it. "Secure mode" is ++ enabled if the effective UID is not the same as the owner of the login session, see ++ geteuid2 ++ and ++ sd_pid_get_owner_uid3. ++ In this case, SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to ++ implement "secure mode" will not be used at all. ++ ++ Note that if the $SYSTEMD_PAGER or $PAGER variables are to ++ be honoured, $SYSTEMD_PAGERSECURE must be set too. ++ + + + diff --git a/SOURCES/1344-pager-also-check-for-SUDO_UID.patch b/SOURCES/1344-pager-also-check-for-SUDO_UID.patch new file mode 100644 index 0000000..3e2dd1e --- /dev/null +++ b/SOURCES/1344-pager-also-check-for-SUDO_UID.patch @@ -0,0 +1,132 @@ +From da56a9f1ec27bdf37928e53f90920a6f452cea51 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 6 May 2025 14:29:02 +0200 +Subject: [PATCH] pager: also check for $SUDO_UID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This returns to the original approach proposed in +https://github.com/systemd/systemd/pull/17270. After review, the approach was +changed to use sd_pid_get_owner_uid() instead. Back then, when running in a +typical graphical session, sd_pid_get_owner_uid() would usually return the user +UID, and when running under sudo, geteuid() would return 0, so we'd trigger the +secure path. + +sudo may allocate a new session if is invoked outside of a session (depending +on the PAM config). Since nowadays desktop environments usually start the user +shell through user units, the typical shell in a terminal emulator is not part +of a session, and when sudo is invoked, a new session is allocated, and +sd_pid_get_owner_uid() returns 0 too. Technically, the code still works as +documented in the man page, but in the common case, it doesn't do the expected +thing. + +$ build/test-sd-login |& rg 'get_(owner_uid|cgroup|session)' +sd_pid_get_session(0) → No data available +sd_pid_get_owner_uid(0) → 1000 +sd_pid_get_cgroup(0) → /user.slice/user-1000.slice/user@1000.service/app.slice/app-ghostty-transient-5088.scope/surfaces/556FAF50BA40.scope + +$ sudo build/test-sd-login |& rg 'get_(owner_uid|cgroup|session)' +sd_pid_get_session(0) → c289 +sd_pid_get_owner_uid(0) → 0 +sd_pid_get_cgroup(0) → /user.slice/user-0.slice/session-c289.scope + +I think it's worth checking for sudo because it is a common case used by users. +There obviously are other mechanims, so the man page is extended to say that +only some common mechanisms are supported, and to (again) recommend setting +SYSTEMD_LESSSECURE explicitly. The other option would be to set "secure mode" +by default. But this would create an inconvenience for users doing the right +thing, running systemctl and other tools directly, because then they can't run +privileged commands from the pager, e.g. to save the output to a file. (Or the +user would need to explicitly set SYSTEMD_LESSSECURE. One option would be to +set it always in the environment and to rely on sudo and other tools stripping +it from the environment before running privileged code. But that is also fairly +fragile and it obviously relies on the user doing a complicated setup to +support a fairly common use case. I think this decreases usability of the +system quite a bit. I don't think we should build solutions that work in +priniciple, but are painfully inconvenient in common cases.) + +Fixes https://yeswehack.com/vulnerability-center/reports/346802. + +Also see https://github.com/polkit-org/polkit/pull/562, which adds support for +$SUDO_UID/$SUDO_GID to pkexec. + +(cherry picked from commit cd93478af8b9dc69478d5667f113b67d175090fa) + +Resolves: RHEL-102941 +--- + man/common-variables.xml | 13 ++++++++++--- + src/shared/pager.c | 29 +++++++++++++++++++---------- + 2 files changed, 29 insertions(+), 13 deletions(-) + +diff --git a/man/common-variables.xml b/man/common-variables.xml +index d6de5ed059..9a45d4d6f2 100644 +--- a/man/common-variables.xml ++++ b/man/common-variables.xml +@@ -177,9 +177,16 @@ + enabled if the effective UID is not the same as the owner of the login session, see + geteuid2 + and +- sd_pid_get_owner_uid3. +- In this case, SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to +- implement "secure mode" will not be used at all. ++ sd_pid_get_owner_uid3, ++ or when running under ++ sudo8 or similar ++ tools ($SUDO_UID is set ++ It is recommended for other tools to set and check $SUDO_UID as appropriate, ++ treating it is a common interface.). In those cases, ++ SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to implement ++ "secure mode" will not be used at all. Note that this autodetection only covers the most common ++ mechanisms to elevate privileges and is intended as convenience. It is recommended to explicitly set ++ $SYSTEMD_PAGERSECURE or disable the pager. + + Note that if the $SYSTEMD_PAGER or $PAGER variables are to + be honoured, $SYSTEMD_PAGERSECURE must be set too. +diff --git a/src/shared/pager.c b/src/shared/pager.c +index dc717cd1fe..41a0b097cd 100644 +--- a/src/shared/pager.c ++++ b/src/shared/pager.c +@@ -83,6 +83,22 @@ static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) { + return r; + } + ++static bool running_with_escalated_privileges(void) { ++ int r; ++ ++ if (getenv("SUDO_UID")) ++ return true; ++ ++ uid_t uid; ++ r = sd_pid_get_owner_uid(0, &uid); ++ if (r < 0) { ++ log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m"); ++ return true; ++ } ++ ++ return uid != geteuid(); ++} ++ + void pager_open(PagerFlags flags) { + _cleanup_close_pair_ int fd[2] = { -1, -1 }, exe_name_pipe[2] = { -1, -1 }; + _cleanup_strv_free_ char **pager_args = NULL; +@@ -178,16 +194,9 @@ void pager_open(PagerFlags flags) { + * know to be good. */ + int use_secure_mode = getenv_bool_secure("SYSTEMD_PAGERSECURE"); + bool trust_pager = use_secure_mode >= 0; +- if (use_secure_mode == -ENXIO) { +- uid_t uid; +- +- r = sd_pid_get_owner_uid(0, &uid); +- if (r < 0) +- log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m"); +- +- use_secure_mode = r < 0 || uid != geteuid(); +- +- } else if (use_secure_mode < 0) { ++ if (use_secure_mode == -ENXIO) ++ use_secure_mode = running_with_escalated_privileges(); ++ else if (use_secure_mode < 0) { + log_warning_errno(use_secure_mode, "Unable to parse $SYSTEMD_PAGERSECURE, assuming true: %m"); + use_secure_mode = true; + } diff --git a/SOURCES/1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch b/SOURCES/1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch new file mode 100644 index 0000000..8f48c30 --- /dev/null +++ b/SOURCES/1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch @@ -0,0 +1,175 @@ +From 395d46b8650031be8d54d5a222fa8e2619f0b6a2 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 16 Jan 2026 23:50:35 +0900 +Subject: [PATCH] hwdb: make three more hwdb files parsed by parse_hwdb.py + +This also makes 70-lights.hwdb installed. The file was introduced by +106f64cbd66b8aa76333c3f11177f53e79e2cd82, but never installed. + +Moreover, this makes the parser also check bluetooth modalias patterns. + +(cherry picked from commit 3da9b65b304836c2c8b1812a8c328f0ce45b18f7) + +Resolves: RHEL-180937 +--- + hwdb.d/20-dmi-id.hwdb | 10 +++++----- + hwdb.d/70-lights.hwdb | 8 ++++---- + hwdb.d/meson.build | 5 +++-- + hwdb.d/parse_hwdb.py | 28 +++++++++++++++++++++++----- + 4 files changed, 35 insertions(+), 16 deletions(-) + +diff --git a/hwdb.d/20-dmi-id.hwdb b/hwdb.d/20-dmi-id.hwdb +index 905d6923bb..50fc1d21a6 100644 +--- a/hwdb.d/20-dmi-id.hwdb ++++ b/hwdb.d/20-dmi-id.hwdb +@@ -9,7 +9,7 @@ dmi:*:svnSystemmanufacturer:* + dmi:*:svnSystemManufacturer:* + dmi:*:svnTobefilledbyO.E.M.:* + dmi:*:svnToBeFilledByO.E.M.:* +- ID_SYS_VENDOR_IS_RUBBISH=1 ++ ID_SYS_VENDOR_IS_RUBBISH=1 + + dmi:*:pnDefaultstring:* + dmi:*:pnN/A:* +@@ -21,13 +21,13 @@ dmi:*:pnSystemname:* + dmi:*:pnSystemName:* + dmi:*:pnTobefilledbyO.E.M.:* + dmi:*:pnToBeFilledByO.E.M.:* +- ID_PRODUCT_NAME_IS_RUBBISH=1 ++ ID_PRODUCT_NAME_IS_RUBBISH=1 + + # Fix "Lenovo" capitalization in /sys/class/dmi/id/sys_vendor + dmi:bvnLENOVO* +- ID_SYSFS_ATTRIBUTE_MODEL=product_version +- ID_VENDOR_FROM_DATABASE=Lenovo ++ ID_SYSFS_ATTRIBUTE_MODEL=product_version ++ ID_VENDOR_FROM_DATABASE=Lenovo + + # Microsoft Surface 1's chassis type + dmi:bvnMicrosoft Corporation*:pvrSurface with Windows 8 Pro* +- ID_CHASSIS=tablet ++ ID_CHASSIS=tablet +diff --git a/hwdb.d/70-lights.hwdb b/hwdb.d/70-lights.hwdb +index a7753710ed..af56968abd 100644 +--- a/hwdb.d/70-lights.hwdb ++++ b/hwdb.d/70-lights.hwdb +@@ -26,11 +26,11 @@ + # Logitech + ################ + # Litra Beam +-bluetooth:v046dpc901* +-usb:v046dpc901* ++bluetooth:v046DpC901* ++usb:v046DpC901* + ID_AV_LIGHTS=1 + + # Litra Glow +-bluetooth:v046dpc900* +-usb:v046dpc900* ++bluetooth:v046DpC900* ++usb:v046DpC900* + ID_AV_LIGHTS=1 +diff --git a/hwdb.d/meson.build b/hwdb.d/meson.build +index e95ccda8c7..0f24f3095c 100644 +--- a/hwdb.d/meson.build ++++ b/hwdb.d/meson.build +@@ -5,7 +5,6 @@ + # So we don't "test" them. + hwdb_files_notest = files( + 'README', +- '20-dmi-id.hwdb', + '20-pci-vendor-model.hwdb', + '20-pci-classes.hwdb', + '20-usb-vendor-model.hwdb', +@@ -15,10 +14,11 @@ hwdb_files_notest = files( + '20-bluetooth-vendor-product.hwdb', + '20-acpi-vendor.hwdb', + '20-OUI.hwdb', +- '20-net-ifname.hwdb', + '20-vmbus-class.hwdb') + + hwdb_files_test = files( ++ '20-dmi-id.hwdb', ++ '20-net-ifname.hwdb', + '60-autosuspend.hwdb', + '60-autosuspend-fingerprint-reader.hwdb', + '60-evdev.hwdb', +@@ -31,6 +31,7 @@ hwdb_files_test = files( + '70-cameras.hwdb', + '70-hardware-wallets.hwdb', + '70-joystick.hwdb', ++ '70-lights.hwdb', + '70-maker-tools.hwdb', + '70-mouse.hwdb', + '70-pda.hwdb', +diff --git a/hwdb.d/parse_hwdb.py b/hwdb.d/parse_hwdb.py +index 9a599e735c..668734b237 100755 +--- a/hwdb.d/parse_hwdb.py ++++ b/hwdb.d/parse_hwdb.py +@@ -106,6 +106,7 @@ GENERAL_MATCHES = {'acpi', + 'vmbus', + 'OUI', + 'ieee1394', ++ 'dmi', + } + + def upperhex_word(length): +@@ -200,6 +201,16 @@ def property_grammar(): + ('ID_INFRARED_CAMERA', Or((Literal('0'), Literal('1')))), + ('ID_CAMERA_DIRECTION', Or(('front', 'rear'))), + ('SOUND_FORM_FACTOR', Or(('internal', 'webcam', 'speaker', 'headphone', 'headset', 'handset', 'microphone'))), ++ ('ID_SYS_VENDOR_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_PRODUCT_NAME_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_PRODUCT_VERSION_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_BOARD_VERSION_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_PRODUCT_SKU_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_CHASSIS_ASSET_TAG_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_CHASSIS', name_literal), ++ ('ID_SYSFS_ATTRIBUTE_MODEL', name_literal), ++ ('ID_NET_NAME_FROM_DATABASE', name_literal), ++ ('ID_NET_NAME_INCLUDE_DOMAIN', Or((Literal('0'), Literal('1')))), + ) + fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') + for name, val in props] +@@ -242,8 +253,10 @@ def check_matches(groups): + + # This is a partial check. The other cases could be also done, but those + # two are most commonly wrong. +- grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', +- 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*', ++ grammars = { ++ 'bluetooth' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', ++ 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', ++ 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*', + } + + for match in matches: +@@ -252,12 +265,12 @@ def check_matches(groups): + if gr: + # we check this first to provide an easy error message + if rest[-1] not in '*:': +- error('pattern {} does not end with "*" or ":"', match) ++ error('Pattern {} does not end with "*" or ":"', match) + + try: + gr.parseString(rest) + except ParseBaseException as e: +- error('Pattern {!r} is invalid: {}', rest, e) ++ error('Pattern {} is invalid: {}', match, e) + continue + + matches.sort() +@@ -339,7 +352,12 @@ def print_summary(fname, groups): + error(f'{fname}: no matches or props') + + if __name__ == '__main__': +- args = sys.argv[1:] or sorted(glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb')) ++ args = sys.argv[1:] or sorted( ++ [ ++ os.path.dirname(sys.argv[0]) + '/20-dmi-id.hwdb', ++ os.path.dirname(sys.argv[0]) + '/20-net-ifname.hwdb', ++ ] + glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb') ++ ) + + for fname in args: + groups = parse(fname) diff --git a/SOURCES/1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch b/SOURCES/1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch new file mode 100644 index 0000000..36097c9 --- /dev/null +++ b/SOURCES/1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch @@ -0,0 +1,109 @@ +From b68c06df98888614397997bb3710aea976fb7473 Mon Sep 17 00:00:00 2001 +From: Roman Vinogradov +Date: Thu, 11 Jun 2026 14:21:55 +0000 +Subject: [PATCH] nss-systemd: avoid ELF TLS for recursion guard + +libnss_systemd currently uses a thread_local recursion guard to +avoid re-entering nss-systemd during NSS lookups. +Since libnss_systemd.so.2 is loaded lazily by glibc, accessing ELF TLS +may trigger dynamic TLS allocation in __tls_get_addr(). Under allocation +failure conditions, glibc terminates the process from the dynamic loader +instead of allowing the NSS module to return a normal failure. +Replace the recursion guard with POSIX thread-specific data to preserve the +same per-thread semantics while avoiding ELF TLS in the NSS module. +Note that pthread_setspecific() may still allocate internally on first use +per thread. The key improvement is that any such failure is returned +as a normal error code rather than terminating the process from inside +the dynamic loader. + +Related to: #42559 +(cherry picked from commit 19bd80e29a02b4f8c9543370eb4a16c014d497f3) + +Resolves: RHEL-193714 +--- + src/nss-systemd/nss-systemd.c | 56 +++++++++++++++++++++++++++++++---- + 1 file changed, 50 insertions(+), 6 deletions(-) + +diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c +index 1d6e25399f..1cb36a153a 100644 +--- a/src/nss-systemd/nss-systemd.c ++++ b/src/nss-systemd/nss-systemd.c +@@ -1057,28 +1057,72 @@ enum nss_status _nss_systemd_initgroups_dyn( + return any ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND; + } + +-static thread_local unsigned _blocked = 0; ++/* Note that we intentionally use POSIX thread-specific data instead of a plain thread_local variable. ++ * A thread_local in this lazily-loaded DSO uses a dynamic TLS model by default and may require ++ * a dynamic TLS allocation. If that allocation fails, glibc calls _exit() from the dynamic linker, ++ * making the failure unrecoverable. Using pthread_key_t avoids ELF TLS entirely and lets any such ++ * failure propagate as a normal error instead of terminating the process. */ ++static pthread_once_t nss_blocked_key_once = PTHREAD_ONCE_INIT; ++static pthread_key_t nss_blocked_key; ++static int nss_blocked_key_error; ++ ++static void nss_blocked_key_init(void) { ++ /* NULL destructor: the per-thread value is a plain integer counter encoded as void*, ++ * not a heap allocation, so nothing needs to be freed at thread exit. ++ * No pthread_key_delete: this library is linked with -z nodelete and always opened with ++ * RTLD_NODELETE, so it is never unloaded and the key exists for the process lifetime. */ ++ nss_blocked_key_error = pthread_key_create(&nss_blocked_key, NULL); ++} ++ ++static int nss_blocked_key_ensure(void) { ++ int r; ++ ++ r = pthread_once(&nss_blocked_key_once, nss_blocked_key_init); ++ if (r != 0) ++ return -r; ++ ++ if (nss_blocked_key_error != 0) ++ return -nss_blocked_key_error; ++ ++ return 0; ++} + + _public_ int _nss_systemd_block(bool b) { ++ int r; ++ uintptr_t blocked; ++ ++ r = nss_blocked_key_ensure(); ++ if (r < 0) ++ return r; ++ ++ blocked = (uintptr_t) pthread_getspecific(nss_blocked_key); + + /* This blocks recursively: it's blocked for as many times this function is called with `true` until + * it is called an equal time with `false`. */ + + if (b) { +- if (_blocked >= UINT_MAX) ++ if (blocked >= UINTPTR_MAX) + return -EOVERFLOW; + +- _blocked++; ++ blocked++; + } else { +- if (_blocked <= 0) ++ if (blocked == 0) + return -EOVERFLOW; + +- _blocked--; ++ blocked--; + } + ++ r = pthread_setspecific(nss_blocked_key, (void*) blocked); ++ /* Ignore failure on the unblock path: callers may assert on it. */ ++ if (r != 0 && b) ++ return -r; ++ + return b; /* Return what is passed in, i.e. the new state from the PoV of the caller */ + } + + _public_ bool _nss_systemd_is_blocked(void) { +- return _blocked > 0; ++ if (nss_blocked_key_ensure() < 0) ++ return false; ++ ++ return (uintptr_t) pthread_getspecific(nss_blocked_key) > 0; + } diff --git a/SOURCES/1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch b/SOURCES/1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch new file mode 100644 index 0000000..93f40f1 --- /dev/null +++ b/SOURCES/1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch @@ -0,0 +1,60 @@ +From 62099c992b6e5887ce5c0bb3a46113544ced9d5b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 11 Mar 2026 11:27:48 +0100 +Subject: [PATCH] udev-builtin-net-id: print cescaped bad attributes + +Follow-up for 16325b35fa6ecb25f66534a562583ce3b96d52f3. Let's +log those bad value to make it easier to figure out why things +are not working if we reject an attribute. + +(cherry picked from commit 7c4047957ef58744ecfad6d277f7c45d430f6d70) + +Resolves: RHEL-180934 +--- + src/udev/udev-builtin-net_id.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 6bb6465832..8003f48eba 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -27,6 +27,7 @@ + #include "device-private.h" + #include "device-util.h" + #include "dirent-util.h" ++#include "escape.h" + #include "ether-addr-util.h" + #include "fd-util.h" + #include "fileio.h" +@@ -44,6 +45,12 @@ + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) + ++static int log_invalid_device_attr(sd_device *dev, const char *attr, const char *value) { ++ _cleanup_free_ char *escaped = cescape(value); ++ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), ++ "Invalid %s value '%s'.", attr, strnull(escaped)); ++} ++ + typedef enum NetNameType { + NET_UNDEF, + NET_PCI, +@@ -701,8 +708,7 @@ static int names_platform(sd_device *dev, NetNames *names, bool test) { + return -EINVAL; + + if (!in_charset(vendor, validchars)) +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENOENT), +- "Platform vendor contains invalid characters: %s", vendor); ++ return log_invalid_device_attr(dev, "platform vendor", vendor); + + ascii_strlower(vendor); + +@@ -1191,7 +1197,7 @@ static int get_link_info(sd_device *dev, LinkInfo *info) { + r = device_get_sysattr_value_filtered(dev, "phys_port_name", &info->phys_port_name); + if (r >= 0) { + if (!utf8_is_valid(info->phys_port_name) || string_has_cc(info->phys_port_name, /* ok= */ NULL)) +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid phys_port_name"); ++ return log_invalid_device_attr(dev, "phys_port_name", info->phys_port_name); + + /* Check if phys_port_name indicates virtual device representor */ + (void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id); diff --git a/SOURCES/1348-udev-drop-redundant-checks.patch b/SOURCES/1348-udev-drop-redundant-checks.patch new file mode 100644 index 0000000..20d9fd6 --- /dev/null +++ b/SOURCES/1348-udev-drop-redundant-checks.patch @@ -0,0 +1,37 @@ +From 010019fa40cb709ea8b111c04301d9a5e7dbbde0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 12 Mar 2026 07:16:46 +0900 +Subject: [PATCH] udev: drop redundant checks + +This partially reverts 16325b35fa6ecb25f66534a562583ce3b96d52f3, +as bad characters are already filtered. + +(cherry picked from commit c5a04f59d912fb2c3451994279dea3ae3064f6c7) + +Resolves: RHEL-180934 +--- + src/udev/udev-builtin-net_id.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 8003f48eba..de2c1fe782 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -40,7 +40,6 @@ + #include "strv.h" + #include "strxcpyx.h" + #include "udev-builtin.h" +-#include "utf8.h" + + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) +@@ -1196,9 +1195,6 @@ static int get_link_info(sd_device *dev, LinkInfo *info) { + + r = device_get_sysattr_value_filtered(dev, "phys_port_name", &info->phys_port_name); + if (r >= 0) { +- if (!utf8_is_valid(info->phys_port_name) || string_has_cc(info->phys_port_name, /* ok= */ NULL)) +- return log_invalid_device_attr(dev, "phys_port_name", info->phys_port_name); +- + /* Check if phys_port_name indicates virtual device representor */ + (void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id); + } diff --git a/SOURCES/1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch b/SOURCES/1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch new file mode 100644 index 0000000..b1d1567 --- /dev/null +++ b/SOURCES/1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch @@ -0,0 +1,51 @@ +From 5553702cddcaf257e8ebee9ea3d3cdf035127d61 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 12 Mar 2026 07:14:44 +0900 +Subject: [PATCH] Revert "udev-builtin-net-id: print cescaped bad attributes" + +This reverts commit 7c4047957ef58744ecfad6d277f7c45d430f6d70. + +This is not necessary, as bad characters are already filtered. + +(cherry picked from commit c6ea72e39a8d829b1bd65f15f6dd7d1c2b6d04c3) + +Resolves: RHEL-180934 +--- + src/udev/udev-builtin-net_id.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index de2c1fe782..d2482f5579 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -27,7 +27,6 @@ + #include "device-private.h" + #include "device-util.h" + #include "dirent-util.h" +-#include "escape.h" + #include "ether-addr-util.h" + #include "fd-util.h" + #include "fileio.h" +@@ -44,12 +43,6 @@ + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) + +-static int log_invalid_device_attr(sd_device *dev, const char *attr, const char *value) { +- _cleanup_free_ char *escaped = cescape(value); +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), +- "Invalid %s value '%s'.", attr, strnull(escaped)); +-} +- + typedef enum NetNameType { + NET_UNDEF, + NET_PCI, +@@ -707,7 +700,8 @@ static int names_platform(sd_device *dev, NetNames *names, bool test) { + return -EINVAL; + + if (!in_charset(vendor, validchars)) +- return log_invalid_device_attr(dev, "platform vendor", vendor); ++ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENOENT), ++ "Platform vendor contains invalid characters: %s", vendor); + + ascii_strlower(vendor); + diff --git a/SOURCES/1350-hwdb-rules-add-82-net-auto-link-local.-hwdb-rules-to.patch b/SOURCES/1350-hwdb-rules-add-82-net-auto-link-local.-hwdb-rules-to.patch new file mode 100644 index 0000000..e0a56c5 --- /dev/null +++ b/SOURCES/1350-hwdb-rules-add-82-net-auto-link-local.-hwdb-rules-to.patch @@ -0,0 +1,57 @@ +From 5262326d17a853e59dcaae88c5d3f618bc8483fe Mon Sep 17 00:00:00 2001 +From: Rebecca Cran +Date: Fri, 5 Dec 2025 11:20:05 -0700 +Subject: [PATCH] hwdb,rules: add 82-net-auto-link-local.{hwdb,rules} to build + +Update hwdb.d/meson.build and rules.d/meson.build to add the +82-net-auto-link-local.{hwdb,rules} files into the build. Commit +ec541c569bd19bbb81791139371111a9a7f1a3d8 in 2023 added the files +but didn't add them to the build system. + +(cherry picked from commit b159befeae014a0c64069afaadfb2b58b7a7f8cd) + +Resolves: RHEL-180938 +--- + hwdb.d/meson.build | 3 ++- + hwdb.d/parse_hwdb.py | 1 + + rules.d/meson.build | 1 + + 3 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hwdb.d/meson.build b/hwdb.d/meson.build +index 0f24f3095c..097ae4ef8c 100644 +--- a/hwdb.d/meson.build ++++ b/hwdb.d/meson.build +@@ -39,7 +39,8 @@ hwdb_files_test = files( + '70-software-radio.hwdb', + '70-sound-card.hwdb', + '70-touchpad.hwdb', +- '80-ieee1394-unit-function.hwdb') ++ '80-ieee1394-unit-function.hwdb', ++ '82-net-auto-link-local.hwdb') + + if conf.get('ENABLE_HWDB') == 1 + auto_suspend_rules = custom_target( +diff --git a/hwdb.d/parse_hwdb.py b/hwdb.d/parse_hwdb.py +index 668734b237..824433179d 100755 +--- a/hwdb.d/parse_hwdb.py ++++ b/hwdb.d/parse_hwdb.py +@@ -181,6 +181,7 @@ def property_grammar(): + ('ID_HARDWARE_WALLET', Or((Literal('0'), Literal('1')))), + ('ID_SOFTWARE_RADIO', Or((Literal('0'), Literal('1')))), + ('ID_MM_DEVICE_IGNORE', Or((Literal('0'), Literal('1')))), ++ ('ID_NET_AUTO_LINK_LOCAL_ONLY', Or((Literal('0'), Literal('1')))), + ('POINTINGSTICK_SENSITIVITY', INTEGER), + ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))), + ('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))), +diff --git a/rules.d/meson.build b/rules.d/meson.build +index 4e88400d02..8327cee78c 100644 +--- a/rules.d/meson.build ++++ b/rules.d/meson.build +@@ -30,6 +30,7 @@ rules = [ + '78-sound-card.rules', + '80-net-setup-link.rules', + '81-net-dhcp.rules', ++ '82-net-auto-link-local.rules', + )], + + [files('80-drivers.rules'), diff --git a/SOURCES/1351-test-reenable-test-for-cg_get_keyed_attribute.patch b/SOURCES/1351-test-reenable-test-for-cg_get_keyed_attribute.patch new file mode 100644 index 0000000..9e077a7 --- /dev/null +++ b/SOURCES/1351-test-reenable-test-for-cg_get_keyed_attribute.patch @@ -0,0 +1,29 @@ +From ece01612cf57d48488f6dfa26d1681a391115722 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sat, 30 Aug 2025 08:08:04 +0900 +Subject: [PATCH] test: reenable test for cg_get_keyed_attribute() + +The test case was mistakenly disabled by +a412a1b92ab234a57c646f6779471772b2c355ec. + +Co-authored-by: Natalie Vock +(cherry picked from commit 194e05642f74993d7be80724f2560f1a698931ec) + +Resolves: RHEL-180940 +--- + src/test/test-cgroup-util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c +index c6439e2fbb..7ac0ba0a77 100644 +--- a/src/test/test-cgroup-util.c ++++ b/src/test/test-cgroup-util.c +@@ -367,7 +367,7 @@ TEST(cg_get_keyed_attribute) { + int i, r; + + r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val); +- if (IN_SET(r, -ENOMEDIUM, -ENOENT) || ERRNO_IS_PRIVILEGE(r)) { ++ if (r == -ENOMEDIUM || ERRNO_IS_PRIVILEGE(r)) { + log_info_errno(r, "Skipping most of %s, /sys/fs/cgroup not accessible: %m", __func__); + return; + } diff --git a/SOURCES/1352-Revert-hwdb-fix-arrow-keys-on-HP-Elite-Dragonfly-G3.patch b/SOURCES/1352-Revert-hwdb-fix-arrow-keys-on-HP-Elite-Dragonfly-G3.patch new file mode 100644 index 0000000..44e3ed6 --- /dev/null +++ b/SOURCES/1352-Revert-hwdb-fix-arrow-keys-on-HP-Elite-Dragonfly-G3.patch @@ -0,0 +1,66 @@ +From e22bea316fe83011f11faf689f2603a4dd9d8791 Mon Sep 17 00:00:00 2001 +From: Han Sol Jin +Date: Mon, 9 Feb 2026 02:23:03 -0800 +Subject: [PATCH] Revert "hwdb: fix arrow keys on HP Elite Dragonfly G3" + +Prior to this commit, the behaviour looked like this: + +| Keypress | Result | +| -------- | ------------ | +| Up | KEY_PAGEUP | +| Down | KEY_PAGEDOWN | +| Left | KEY_LEFT | +| Right | KEY_RIGHT | +| Fn+Up | KEY_UP | +| Fn+Down | KEY_DOWN | +| Fn+Left | KEY_HOME | +| Fn+Right | KEY_END | + +This commit would fix it so that PGUP/PGDN would also require the Fn +key so that the arrow keys behave identically depending on whether Fn +was pressed. + +Presumably after a BIOS update, HP seems to have fixed the order. This +now means this commit is now behaving exactly as the table above. + +Revert the commit to restore the intended behaviour: + +| Keypress | Result | +| -------- | ------------ | +| Up | KEY_UP | +| Down | KEY_DOWN | +| Left | KEY_LEFT | +| Right | KEY_RIGHT | +| Fn+Up | KEY_PAGEUP | +| Fn+Down | KEY_PAGEDOWN | +| Fn+Left | KEY_HOME | +| Fn+Right | KEY_END | + +This reverts commit 4fd7c712dcba3c4ed7183ba327d0b88d9b0be9bb. + +Signed-off-by: Han Sol Jin +(cherry picked from commit 09b9466e8c6fa8a898769bbbebda513b05251054) + +Resolves: RHEL-180939 +--- + hwdb.d/60-keyboard.hwdb | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/hwdb.d/60-keyboard.hwdb b/hwdb.d/60-keyboard.hwdb +index 465d527817..ba7ddfd1e1 100644 +--- a/hwdb.d/60-keyboard.hwdb ++++ b/hwdb.d/60-keyboard.hwdb +@@ -918,13 +918,6 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPEliteDragonflyG2*:pvr* + evdev:name:Intel HID events:dmi:bvn*:bvr*:bd*:svnHP*:pnHPEliteDragonflyG2*:pvr* + KEYBOARD_KEY_08=unknown # rfkill is also reported by HP Wireless hotkeys + +-# HP Elite Dragonfly G3 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteDragonfly13.5inchG3NotebookPC:pvr* +- KEYBOARD_KEY_c9=up +- KEYBOARD_KEY_d1=down +- KEYBOARD_KEY_c8=pageup +- KEYBOARD_KEY_d0=pagedown +- + # HP 430 Programmable Wireless Keypad + evdev:input:b0005v03F0p854Ae044C* + KEYBOARD_KEY_700f3=macro1 diff --git a/SOURCES/1353-ci-bump-the-mkosi-job-to-Ubuntu-Noble.patch b/SOURCES/1353-ci-bump-the-mkosi-job-to-Ubuntu-Noble.patch new file mode 100644 index 0000000..22c6229 --- /dev/null +++ b/SOURCES/1353-ci-bump-the-mkosi-job-to-Ubuntu-Noble.patch @@ -0,0 +1,64 @@ +From 057d8cd08ae99ba09bc0ed280887963e8ae53818 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 20 Jul 2026 18:00:42 +0200 +Subject: [PATCH] ci: bump the mkosi job to Ubuntu Noble + +This should help with the missing pacman-package-manager package in the +mkosi job. + +rhel-only: ci +Related: RHEL-155457 +--- + .github/workflows/mkosi.yml | 4 ++-- + mkosi.images/initrd/mkosi.conf | 2 +- + mkosi.images/system/mkosi.conf | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml +index 2694ba14ec..0fa3141b5f 100644 +--- a/.github/workflows/mkosi.yml ++++ b/.github/workflows/mkosi.yml +@@ -48,7 +48,7 @@ permissions: + + jobs: + ci: +- runs-on: ubuntu-22.04 ++ runs-on: ubuntu-24.04 + concurrency: + group: ${{ github.workflow }}-${{ matrix.distro }}-${{ matrix.release }}-${{ github.ref }} + cancel-in-progress: true +@@ -64,7 +64,7 @@ jobs: + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 +- - uses: systemd/mkosi@070528fec478fc93af7ec057a5d2fd0045123c99 ++ - uses: systemd/mkosi@857838464970f1092cc0107f4b1df714d0744990 + + - name: Configure + run: | +diff --git a/mkosi.images/initrd/mkosi.conf b/mkosi.images/initrd/mkosi.conf +index 8e38dc1b78..628a13fe37 100644 +--- a/mkosi.images/initrd/mkosi.conf ++++ b/mkosi.images/initrd/mkosi.conf +@@ -8,7 +8,7 @@ Format=cpio + + [Content] + BaseTrees=../../mkosi.output/base +-ExtraTrees=../../mkosi.output/base-systemd ++ExtraTrees=../../mkosi.output/systemd + MakeInitrd=yes + Bootable=no + BuildPackages= +diff --git a/mkosi.images/system/mkosi.conf b/mkosi.images/system/mkosi.conf +index 9646bbefde..a28ba930e3 100644 +--- a/mkosi.images/system/mkosi.conf ++++ b/mkosi.images/system/mkosi.conf +@@ -9,7 +9,7 @@ Dependencies=base + [Content] + Autologin=yes + BaseTrees=../../mkosi.output/base +-ExtraTrees=../../mkosi.output/base-systemd ++ExtraTrees=../../mkosi.output/systemd + Packages= + acl + bash-completion diff --git a/SOURCES/1354-ci-bump-super-linter-to-v8.7.0.patch b/SOURCES/1354-ci-bump-super-linter-to-v8.7.0.patch new file mode 100644 index 0000000..a109607 --- /dev/null +++ b/SOURCES/1354-ci-bump-super-linter-to-v8.7.0.patch @@ -0,0 +1,28 @@ +From 420652432af30cbb55e716d8bc9895cbfc17db97 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 20 Jul 2026 19:10:23 +0200 +Subject: [PATCH] ci: bump super-linter to v8.7.0 + +So it recognizes the ubuntu-24.04 label. + +Taken from systemd/systemd@b82af8adcf4bdb27f35bc357e200dc3af4171bc7. + +rhel-only: ci +Related: RHEL-155457 +--- + .github/workflows/linter.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml +index 8dd3b075ad..31c7d790b1 100644 +--- a/.github/workflows/linter.yml ++++ b/.github/workflows/linter.yml +@@ -29,7 +29,7 @@ jobs: + fetch-depth: 0 + + - name: Lint Code Base +- uses: github/super-linter/slim@01d3218744765b55c3b5ffbb27e50961e50c33c5 ++ uses: github/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 + env: + DEFAULT_BRANCH: main + VALIDATE_ALL_CODEBASE: false diff --git a/SOURCES/1355-ci-explicitly-disable-multi-status-for-Super-Linter.patch b/SOURCES/1355-ci-explicitly-disable-multi-status-for-Super-Linter.patch new file mode 100644 index 0000000..96e315e --- /dev/null +++ b/SOURCES/1355-ci-explicitly-disable-multi-status-for-Super-Linter.patch @@ -0,0 +1,29 @@ +From 6850151e8df81aafeb24f726e79f6820aa072bd1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 2 May 2024 09:45:02 +0200 +Subject: [PATCH] ci: explicitly disable multi status for Super-Linter + +The multi status feature requires $GITHUB_TOKEN, and since [0] it +defaults to true. Since we don't need it, let's explicitly disable the +feature. + +[0] https://github.com/super-linter/super-linter/commit/e6e6e1fa5f60e15d7e9b89248bb0809bea1c17e9 + +(cherry picked from commit b160ac9c126d904358a83a18542e0a37d9ca0d5c) + +Related: RHEL-155457 +--- + .github/workflows/linter.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml +index 31c7d790b1..a7749149ad 100644 +--- a/.github/workflows/linter.yml ++++ b/.github/workflows/linter.yml +@@ -32,5 +32,6 @@ jobs: + uses: github/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 + env: + DEFAULT_BRANCH: main ++ MULTI_STATUS: false + VALIDATE_ALL_CODEBASE: false + VALIDATE_GITHUB_ACTIONS: true diff --git a/SOURCES/1356-github-linter-disable-ENABLE_GITHUB_PULL_REQUEST_SUM.patch b/SOURCES/1356-github-linter-disable-ENABLE_GITHUB_PULL_REQUEST_SUM.patch new file mode 100644 index 0000000..15ca80d --- /dev/null +++ b/SOURCES/1356-github-linter-disable-ENABLE_GITHUB_PULL_REQUEST_SUM.patch @@ -0,0 +1,33 @@ +From ded04794fb290b8bb4ce918fb72dac618f54fc9b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 3 Feb 2026 08:59:38 +0900 +Subject: [PATCH] github/linter: disable + ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT for super-linter + +Since super-linter 8.4.0, it is enabled by default and requires GITHUB_TOKEN. +We do not provide GITHUB_TOKEN for the action, then it fails with the following: +``` +Failed to get [GITHUB_TOKEN]. Terminating because status reports were explicitly enabled, +but GITHUB_TOKEN was not provided. +``` + +Also, even if GITHUB_TOKEN is set, the feature provides annoying +messages in each PR. See https://github.com/super-linter/super-linter/issues/7458 +So, let's disable the feature. + +(cherry picked from commit 90c71778d2bcccbdc70e740a8d706dadd49b8e69) + +Related: RHEL-155457 +--- + .github/workflows/linter.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml +index a7749149ad..213eee9094 100644 +--- a/.github/workflows/linter.yml ++++ b/.github/workflows/linter.yml +@@ -35,3 +35,4 @@ jobs: + MULTI_STATUS: false + VALIDATE_ALL_CODEBASE: false + VALIDATE_GITHUB_ACTIONS: true ++ ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT: false diff --git a/SOURCES/1357-test-install-iscsi-gen-initiatorname-from-iscsi-init.patch b/SOURCES/1357-test-install-iscsi-gen-initiatorname-from-iscsi-init.patch new file mode 100644 index 0000000..9924fe3 --- /dev/null +++ b/SOURCES/1357-test-install-iscsi-gen-initiatorname-from-iscsi-init.patch @@ -0,0 +1,31 @@ +From 93d0c6945db72a20759bd3fb653f6091541aaa04 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 20 Jul 2026 20:17:23 +0200 +Subject: [PATCH] test: install iscsi-gen-initiatorname from + iscsi-initiator-utils + +The iscsi-init.service started quite recently [0] depending on an +external script instead of using an inline one. Let's install it into +the test image to make the iSCSI-related tests happy again. + +[0] https://gitlab.com/redhat/centos-stream/rpms/iscsi-initiator-utils/-/commit/d864f8c6e2acda4e6131e334771c9c9d987dc0dc + +rhel-only: ci +Related: RHEL-155457 +--- + test/test-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index 52eff07510..76fc1f5437 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -1036,7 +1036,7 @@ install_iscsi() { + # Install client-side stuff ("initiator" in iSCSI jargon) - Open-iSCSI in this case + # (open-iscsi on Debian, iscsi-initiator-utils on Fedora, etc.) + if [[ -z "$inst" || "$inst" =~ (client|initiator) ]]; then +- image_install iscsi-iname iscsiadm iscsid iscsistart ++ image_install iscsi-iname iscsiadm iscsid iscsistart iscsi-gen-initiatorname + image_install -o "${ROOTLIBDIR:?}"/system/iscsi-{init,onboot,shutdown}.service + image_install "${ROOTLIBDIR:?}"/system/iscsid.{service,socket} + image_install "${ROOTLIBDIR:?}"/system/iscsi.service diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index e983b12..412f80b 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -21,7 +21,7 @@ Name: systemd Url: https://systemd.io Version: 252 -Release: 67%{?dist} +Release: 73%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -1408,10 +1408,42 @@ Patch1322: 1322-tmpfiles-teach-tmpfiles-the-new-XDG_STATE_HOME-varia.patch Patch1323: 1323-test-use-XDG_STATE_HOME-for-S-and-L.patch Patch1324: 1324-man-fully-adopt-.local-state.patch Patch1325: 1325-core-only-activate-transaction-that-contain-useful-j.patch +Patch1326: 1326-integritysetup-Add-support-for-hmac-sha512.patch +Patch1327: 1327-integritysetup-Add-PHMAC-algorithm-to-list-of-known-.patch +Patch1328: 1328-manager-fix-scope-for-environment-generators.patch +Patch1329: 1329-core-validate-input-cgroup-path-more-prudently.patch +Patch1330: 1330-nspawn-apply-BindUser-Ephemeral-from-settings-file-o.patch +Patch1331: 1331-nspawn-normalize-pivot_root-paths.patch +Patch1332: 1332-core-service-do-not-propagate-reload-for-combined-RE.patch +Patch1333: 1333-udev-check-for-invalid-chars-in-various-fields-recei.patch +Patch1334: 1334-udev-fix-review-mixup.patch +Patch1335: 1335-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch +Patch1336: 1336-core-cleanup-unit-s-dropin-directories-from-global-c.patch +Patch1337: 1337-udev-allow-persistent-storage-rules-for-rbd-devices.patch +Patch1338: 1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch +Patch1339: 1339-fstab-generator-support-swap-on-network-block-device.patch +Patch1340: 1340-core-increment-start-limit-counter-only-when-we-can-.patch +Patch1341: 1341-TEST-07-PID1-wait-for-systemd-resolved-being-stopped.patch +Patch1342: 1342-test-extend-start-limit-interval.patch +Patch1343: 1343-man-reword-the-description-of-secure-pager-handling.patch +Patch1344: 1344-pager-also-check-for-SUDO_UID.patch +Patch1345: 1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch +Patch1346: 1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch +Patch1347: 1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch +Patch1348: 1348-udev-drop-redundant-checks.patch +Patch1349: 1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch +Patch1350: 1350-hwdb-rules-add-82-net-auto-link-local.-hwdb-rules-to.patch +Patch1351: 1351-test-reenable-test-for-cg_get_keyed_attribute.patch +Patch1352: 1352-Revert-hwdb-fix-arrow-keys-on-HP-Elite-Dragonfly-G3.patch +Patch1353: 1353-ci-bump-the-mkosi-job-to-Ubuntu-Noble.patch +Patch1354: 1354-ci-bump-super-linter-to-v8.7.0.patch +Patch1355: 1355-ci-explicitly-disable-multi-status-for-Super-Linter.patch +Patch1356: 1356-github-linter-disable-ENABLE_GITHUB_PULL_REQUEST_SUM.patch +Patch1357: 1357-test-install-iscsi-gen-initiatorname-from-iscsi-init.patch # Downstream-only patches (9000–9999) -%ifarch %{ix86} x86_64 aarch64 +%ifarch x86_64 aarch64 %global have_gnu_efi 1 %endif @@ -2285,6 +2317,51 @@ systemd-hwdb update &>/dev/null || : %{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/* %changelog +* Tue Jul 21 2026 systemd maintenance team - 252-73 +- hwdb,rules: add 82-net-auto-link-local.{hwdb,rules} to build (RHEL-180938) +- test: reenable test for cg_get_keyed_attribute() (RHEL-180940) +- Revert "hwdb: fix arrow keys on HP Elite Dragonfly G3" (RHEL-180939) +- ci: bump the mkosi job to Ubuntu Noble (RHEL-155457) +- ci: bump super-linter to v8.7.0 (RHEL-155457) +- ci: explicitly disable multi status for Super-Linter (RHEL-155457) +- github/linter: disable ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT for super-linter (RHEL-155457) +- test: install iscsi-gen-initiatorname from iscsi-initiator-utils (RHEL-155457) + +* Thu Jul 16 2026 systemd maintenance team - 252-72 +- man: reword the description of "secure pager" handling (RHEL-102941) +- pager: also check for $SUDO_UID (RHEL-102941) +- hwdb: make three more hwdb files parsed by parse_hwdb.py (RHEL-180937) +- nss-systemd: avoid ELF TLS for recursion guard (RHEL-193714) +- udev-builtin-net-id: print cescaped bad attributes (RHEL-180934) +- udev: drop redundant checks (RHEL-180934) +- Revert "udev-builtin-net-id: print cescaped bad attributes" (RHEL-180934) + +* Tue Jun 09 2026 systemd maintenance team - 252-71 +- Do not build efi stub on i686 anymore (RHEL-176073) + +* Tue May 12 2026 systemd maintenance team - 252-70 +- core: cleanup unit's dropin directories from global cache (RHEL-127425) +- udev: allow persistent storage rules for rbd devices (RHEL-3631) +- udev/net_id: introduce naming scheme for RHEL-9.9 (RHEL-25518) +- fstab-generator: support swap on network block devices (RHEL-166187) +- core: increment start limit counter only when we can start the unit (RHEL-164539) +- TEST-07-PID1: wait for systemd-resolved being stopped (RHEL-164539) +- test: extend start limit interval (RHEL-164539) + +* Thu Apr 16 2026 systemd maintenance team - 252-69 +- nspawn: apply BindUser/Ephemeral from settings file only if trusted (RHEL-163871) +- nspawn: normalize pivot_root paths (RHEL-163871) +- core/service: do not propagate reload for combined RELOADING=1 + READY=1 when notify-reload (RHEL-108575) +- udev: check for invalid chars in various fields received from the kernel (RHEL-163877) +- udev: fix review mixup (RHEL-163877) +- udev/scsi-id: check for invalid chars in various fields received from the kernel (RHEL-163877) + +* Wed Apr 08 2026 systemd maintenance team - 252-68 +- integritysetup: Add support for hmac-sha512 (RHEL-50213) +- integritysetup: Add PHMAC algorithm to list of known algorithms (RHEL-50213) +- manager: fix scope for environment generators (RHEL-159230) +- core: validate input cgroup path more prudently (RHEL-155393) + * Mon Feb 23 2026 systemd maintenance team - 252-67 - core: only activate transaction that contain useful jobs (RHEL-143727)