systemd-252-72

Resolves: RHEL-102941, RHEL-180937, RHEL-193714, RHEL-180934
This commit is contained in:
Jan Macku 2026-07-16 13:12:47 +02:00
parent 479809cb6e
commit 52b8863288
8 changed files with 671 additions and 1 deletions

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

@ -21,7 +21,7 @@
Name: systemd
Url: https://systemd.io
Version: 252
Release: 71%{?dist}
Release: 72%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -1425,6 +1425,13 @@ 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
# Downstream-only patches (90009999)
@ -2302,6 +2309,15 @@ systemd-hwdb update &>/dev/null || :
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
%changelog
* 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)