import CS systemd-252-73.el9

This commit is contained in:
AlmaLinux RelEng Bot 2026-08-24 09:43:55 -04:00
parent 7a1189d5b7
commit de393c2047
33 changed files with 2648 additions and 2 deletions

View File

@ -0,0 +1,78 @@
From 24eef4e6cc9bde4b96d72fbd5b438d774f1ce66a Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
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 @@
<para>The third field if present contains an absolute filename path to a key file or a <literal>-</literal>
to specify none. When the filename is present, the "integrity-algorithm" defaults to <literal>hmac-sha256</literal>
- 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.
</para>
<para>The fourth field, if present, is a comma-delimited list of options or a <literal>-</literal> to specify none. The following options are
@@ -101,7 +101,7 @@
</varlistentry>
<varlistentry>
- <term><option>integrity-algorithm=[crc32c|crc32|sha1|sha256|hmac-sha256]</option></term>
+ <term><option>integrity-algorithm=[crc32c|crc32|sha1|sha256|hmac-sha256|hmac-sha512]</option></term>
<listitem><para>
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;

View File

@ -0,0 +1,84 @@
From 2ce62a32b85b8bc756c34d31d10d343bd2c088f5 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
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 @@
<para>The third field if present contains an absolute filename path to a key file or a <literal>-</literal>
to specify none. When the filename is present, the "integrity-algorithm" defaults to <literal>hmac-sha256</literal>
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.
</para>
<para>The fourth field, if present, is a comma-delimited list of options or a <literal>-</literal> to specify none. The following options are
@@ -101,7 +101,7 @@
</varlistentry>
<varlistentry>
- <term><option>integrity-algorithm=[crc32c|crc32|sha1|sha256|hmac-sha256|hmac-sha512]</option></term>
+ <term><option>integrity-algorithm=[crc32c|crc32|sha1|sha256|hmac-sha256|hmac-sha512|phmac-sha256|phmac-sha512]</option></term>
<listitem><para>
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;

View File

@ -0,0 +1,27 @@
From db8eba6c0d1d34086173657cfcd72737d94e8e20 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
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();

View File

@ -0,0 +1,29 @@
From f7a9f500ea223e8cee700d0acdc3a298fb3e0a58 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
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,

View File

@ -0,0 +1,55 @@
From 6615811a8c6a36677a389ada8cd7be10e9756e58 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
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)

View File

@ -0,0 +1,32 @@
From cfb234e332fe820ef843fb817598ebbbdffdd05f Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
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);

View File

@ -0,0 +1,81 @@
From 3fe4b84a1c363e187be6fc30a19fbf2e66471473 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
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")) {

View File

@ -0,0 +1,110 @@
From 967b7954b78bc59e0247e908ea74b19da7112b39 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
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 <linux/videodev2.h>
#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;

View File

@ -0,0 +1,32 @@
From 320ca2d881198cab52b4c6dd073967f2d4b2e919 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
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;
}

View File

@ -0,0 +1,52 @@
From a7e7bf455cb22e95c4487c91cd040e3c27fa64e7 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
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;
}

View File

@ -0,0 +1,42 @@
From 4843d4f679bb4dd70f15ce49f0786e80bb821e28 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
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);
}

View File

@ -0,0 +1,41 @@
From b7156edf92d815ad3bf84fbcaaa7a4a94a648999 Mon Sep 17 00:00:00 2001
From: Peter Rajnoha <prajnoha@redhat.com>
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"

View File

@ -0,0 +1,55 @@
From 1aaebe972b912e1f2ef3b874edb22e47f7def5b9 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
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 @@
<para>PCI slot number is now read from <constant>firmware_node/sun</constant> sysfs file.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><constant>rhel-9.9</constant></term>
+
+ <listitem><para>Same as naming scheme <constant>rhel-9.8</constant>.</para></listitem>
+ </varlistentry>
+
</variablelist>
<para>By default <constant>rhel-9.0</constant> is used.</para>
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

View File

@ -0,0 +1,322 @@
From e5e4bfa6dcdc2502e57c813ea0d0a72ee37fb337 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
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 <noreply@anthropic.com>
(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 @@
<para>The following dependencies are added unless <varname>DefaultDependencies=no</varname> is set:</para>
<itemizedlist>
- <listitem><para>Swap units automatically acquire a <varname>Conflicts=</varname> and a
+ <listitem><para>Local swap units automatically acquire a <varname>Conflicts=</varname> and a
<varname>Before=</varname> dependency on <filename>umount.target</filename> so that they are deactivated at
shutdown as well as a <varname>Before=swap.target</varname> dependency.</para></listitem>
+
+ <listitem><para>Network swap units (those with <option>_netdev</option> in their options) automatically acquire
+ <varname>After=</varname> dependencies on <filename>remote-fs-pre.target</filename> and
+ <filename>network.target</filename>, plus <varname>After=</varname> and <varname>Wants=</varname> dependencies
+ on <filename>network-online.target</filename>, and a <varname>Before=</varname> dependency on
+ <filename>remote-fs.target</filename> instead of <filename>swap.target</filename>.</para></listitem>
</itemizedlist>
</refsect2>
</refsect1>
@@ -124,7 +130,8 @@
<listitem><para>With <option>noauto</option>, the swap unit
will not be added as a dependency for
- <filename>swap.target</filename>. This means that it will not
+ <filename>swap.target</filename> (or <filename>remote-fs.target</filename> for network swap devices,
+ see <option>_netdev</option> below). This means that it will not
be activated automatically during boot, unless it is pulled in
by some other unit. The <option>auto</option> option has the
opposite meaning and is the default.</para>
@@ -136,8 +143,8 @@
<listitem><para>With <option>nofail</option>, the swap unit
will be only wanted, not required by
- <filename>swap.target</filename>. This means that the boot
- will continue even if this swap device is not activated
+ <filename>swap.target</filename> (or <filename>remote-fs.target</filename> for network swap
+ devices). This means that the boot will continue even if this swap device is not activated
successfully.</para>
</listitem>
</varlistentry>
@@ -161,6 +168,19 @@
in <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>_netdev</option></term>
+
+ <listitem><para>Marks this swap device as requiring network access. This is useful for swap on
+ network block devices (e.g. iSCSI).</para>
+
+ <para>Network swap units are ordered between <filename>remote-fs-pre.target</filename> and
+ <filename>remote-fs.target</filename>, instead of being ordered before
+ <filename>swap.target</filename>. They also pull in <filename>network-online.target</filename> and
+ are ordered after it and <filename>network.target</filename>.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
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

View File

@ -0,0 +1,460 @@
From 4060cdad388b0ae658f2024633b842a46c37962e Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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 <<EOF
+[Unit]
+StartLimitBurst=5
+StartLimitInterval=30
+
+[Service]
+ExecStopPost=sleep 10
+EOF
+
+systemctl daemon-reload
+systemctl restart systemd-resolved.service
+systemctl reset-failed systemd-resolved.service
+systemctl status --no-pager systemd-resolved.service
+systemctl show systemd-resolved.service | grep StartLimit
+
+for i in {1..5}; do
+ echo "Start #$i"
+
+ systemctl stop --no-block systemd-resolved.service
+ if ! resolvectl; then
+ journalctl -o short-monotonic --no-hostname --no-pager -u systemd-resolved.service -n 15
+ exit 1
+ fi
+done

View File

@ -0,0 +1,38 @@
From 769a4fd1ad342ff84e985f0b73f23e03bbb677db Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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

View File

@ -0,0 +1,40 @@
From d092520e2c3221e191b46c6c771d54ec51f678dc Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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 <<EOF
[Unit]
StartLimitBurst=5
-StartLimitInterval=30
+StartLimitInterval=100
[Service]
ExecStopPost=sleep 10
@@ -42,4 +42,5 @@ for i in {1..5}; do
journalctl -o short-monotonic --no-hostname --no-pager -u systemd-resolved.service -n 15
exit 1
fi
+ systemctl is-active systemd-resolved.service
done

View File

@ -0,0 +1,90 @@
From f90bfb526b0cec607df2cdb6d006912dbb1bb394 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
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 @@
<varlistentry id='lesssecure'>
<term><varname>$SYSTEMD_PAGERSECURE</varname></term>
- <listitem><para>Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if
- false, disabled. If <varname>$SYSTEMD_PAGERSECURE</varname> 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
- <citerefentry project='man-pages'><refentrytitle>geteuid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- and <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- In secure mode, <option>LESSSECURE=1</option> will be set when invoking the pager, and the pager shall
- disable commands that open or create new files or start new subprocesses. When
- <varname>$SYSTEMD_PAGERSECURE</varname> is not set at all, pagers which are not known to implement
- secure mode will not be used. (Currently only
- <citerefentry project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- implements secure mode.)</para>
-
- <para>Note: when commands are invoked with elevated privileges, for example under <citerefentry
+ <listitem>
+ <para>Common pager commands like <citerefentry
+ project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry>, 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 <citerefentry
project='man-pages'><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry> or
<citerefentry
- project='die-net'><refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>, 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 <varname>SYSTEMD_PAGERSECURE=0</varname>
- or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note
- that if the <varname>$SYSTEMD_PAGER</varname> or <varname>$PAGER</varname> variables are to be
- honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too. It might be reasonable to completely
- disable the pager using <option>--no-pager</option> instead.</para></listitem>
+ project='die-net'><refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>, 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, <emphasis>if the pager supports that</emphasis> (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 <option>--no-pager</option> or <varname>PAGER=cat</varname> when
+ allowing untrusted users to execute commands with elevated privileges.</para>
+
+ <para>This option takes a boolean argument. When set to true, the "secure mode" of the pager is
+ enabled. In "secure mode", <option>LESSSECURE=1</option> 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 <citerefentry
+ project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> is known
+ to understand this variable and implement "secure mode".</para>
+
+ <para>When set to false, no limitation is placed on the pager. Setting
+ <varname>SYSTEMD_PAGERSECURE=0</varname> or not removing it from the inherited environment may allow
+ the user to invoke arbitrary commands.</para>
+
+ <para>When <varname>$SYSTEMD_PAGERSECURE</varname> 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
+ <citerefentry project='man-pages'><refentrytitle>geteuid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ and
+ <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ In this case, <varname>SYSTEMD_PAGERSECURE=1</varname> will be set and pagers which are not known to
+ implement "secure mode" will not be used at all.</para>
+
+ <para>Note that if the <varname>$SYSTEMD_PAGER</varname> or <varname>$PAGER</varname> variables are to
+ be honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too.</para>
+ </listitem>
</varlistentry>
<varlistentry id='colors'>

View File

@ -0,0 +1,132 @@
From da56a9f1ec27bdf37928e53f90920a6f452cea51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
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
<citerefentry project='man-pages'><refentrytitle>geteuid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
and
- <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- In this case, <varname>SYSTEMD_PAGERSECURE=1</varname> will be set and pagers which are not known to
- implement "secure mode" will not be used at all.</para>
+ <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ or when running under
+ <citerefentry><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry> or similar
+ tools (<varname>$SUDO_UID</varname> is set <footnote>
+ <para>It is recommended for other tools to set and check <varname>$SUDO_UID</varname> as appropriate,
+ treating it is a common interface.</para></footnote>). In those cases,
+ <varname>SYSTEMD_PAGERSECURE=1</varname> 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
+ <varname>$SYSTEMD_PAGERSECURE</varname> or disable the pager.</para>
<para>Note that if the <varname>$SYSTEMD_PAGER</varname> or <varname>$PAGER</varname> variables are to
be honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too.</para>
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;
}

View File

@ -0,0 +1,175 @@
From 395d46b8650031be8d54d5a222fa8e2619f0b6a2 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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)

View File

@ -0,0 +1,109 @@
From b68c06df98888614397997bb3710aea976fb7473 Mon Sep 17 00:00:00 2001
From: Roman Vinogradov <roman.vinogradov@sap.com>
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;
}

View File

@ -0,0 +1,60 @@
From 62099c992b6e5887ce5c0bb3a46113544ced9d5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@amutable.com>
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);

View File

@ -0,0 +1,37 @@
From 010019fa40cb709ea8b111c04301d9a5e7dbbde0 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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);
}

View File

@ -0,0 +1,51 @@
From 5553702cddcaf257e8ebee9ea3d3cdf035127d61 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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);

View File

@ -0,0 +1,57 @@
From 5262326d17a853e59dcaae88c5d3f618bc8483fe Mon Sep 17 00:00:00 2001
From: Rebecca Cran <rebecca@bsdio.com>
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'),

View File

@ -0,0 +1,29 @@
From ece01612cf57d48488f6dfa26d1681a391115722 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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 <natalie.vock@gmx.de>
(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;
}

View File

@ -0,0 +1,66 @@
From e22bea316fe83011f11faf689f2603a4dd9d8791 Mon Sep 17 00:00:00 2001
From: Han Sol Jin <hansol@hansol.ca>
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 <hansol@hansol.ca>
(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

View File

@ -0,0 +1,64 @@
From 057d8cd08ae99ba09bc0ed280887963e8ae53818 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
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

View File

@ -0,0 +1,28 @@
From 420652432af30cbb55e716d8bc9895cbfc17db97 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
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

View File

@ -0,0 +1,29 @@
From 6850151e8df81aafeb24f726e79f6820aa072bd1 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
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

View File

@ -0,0 +1,33 @@
From ded04794fb290b8bb4ce918fb72dac618f54fc9b Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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

View File

@ -0,0 +1,31 @@
From 93d0c6945db72a20759bd3fb653f6091541aaa04 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
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

View File

@ -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 (90009999)
%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 <systemd-maint@redhat.com> - 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 <systemd-maint@redhat.com> - 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 <systemd-maint@redhat.com> - 252-71
- Do not build efi stub on i686 anymore (RHEL-176073)
* Tue May 12 2026 systemd maintenance team <systemd-maint@redhat.com> - 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 <systemd-maint@redhat.com> - 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 <systemd-maint@redhat.com> - 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 <systemd-maint@redhat.com> - 252-67
- core: only activate transaction that contain useful jobs (RHEL-143727)