systemd-252-72
Resolves: RHEL-102941, RHEL-180937, RHEL-193714, RHEL-180934
This commit is contained in:
parent
479809cb6e
commit
52b8863288
@ -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'>
|
||||
132
1344-pager-also-check-for-SUDO_UID.patch
Normal file
132
1344-pager-also-check-for-SUDO_UID.patch
Normal 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;
|
||||
}
|
||||
175
1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch
Normal file
175
1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch
Normal 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)
|
||||
109
1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch
Normal file
109
1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch
Normal 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;
|
||||
}
|
||||
60
1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch
Normal file
60
1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch
Normal 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);
|
||||
37
1348-udev-drop-redundant-checks.patch
Normal file
37
1348-udev-drop-redundant-checks.patch
Normal 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);
|
||||
}
|
||||
@ -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);
|
||||
|
||||
18
systemd.spec
18
systemd.spec
@ -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 (9000–9999)
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user