diff --git a/1343-man-reword-the-description-of-secure-pager-handling.patch b/1343-man-reword-the-description-of-secure-pager-handling.patch new file mode 100644 index 0000000..6f9adeb --- /dev/null +++ b/1343-man-reword-the-description-of-secure-pager-handling.patch @@ -0,0 +1,90 @@ +From f90bfb526b0cec607df2cdb6d006912dbb1bb394 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 6 May 2025 11:14:10 +0200 +Subject: [PATCH] man: reword the description of "secure pager" handling + +The existing description was not *wrong*, but it was a bit muddled. Let's +reorder the text to give a short intro and then describe what the options +actually do and the clear "true" and "false" cases first, and then describe +autodetection. + +Related to https://yeswehack.com/vulnerability-center/reports/346802. + +(cherry picked from commit 718dbdb2ca4458cf91711cd9a7de3a972e46658e) + +Related: RHEL-102941 +--- + man/common-variables.xml | 58 ++++++++++++++++++++++++++-------------- + 1 file changed, 38 insertions(+), 20 deletions(-) + +diff --git a/man/common-variables.xml b/man/common-variables.xml +index 0e220b3f9e..d6de5ed059 100644 +--- a/man/common-variables.xml ++++ b/man/common-variables.xml +@@ -144,28 +144,46 @@ + + $SYSTEMD_PAGERSECURE + +- Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if +- false, disabled. If $SYSTEMD_PAGERSECURE is not set at all, secure mode is enabled +- if the effective UID is not the same as the owner of the login session, see +- geteuid2 +- and sd_pid_get_owner_uid3. +- In secure mode, will be set when invoking the pager, and the pager shall +- disable commands that open or create new files or start new subprocesses. When +- $SYSTEMD_PAGERSECURE is not set at all, pagers which are not known to implement +- secure mode will not be used. (Currently only +- less1 +- implements secure mode.) +- +- Note: when commands are invoked with elevated privileges, for example under ++ Common pager commands like less1, in ++ addition to "paging", i.e. scrolling through the output, support opening of or writing to other files ++ and running arbitrary shell commands. When commands are invoked with elevated privileges, for example ++ under sudo8 or + pkexec1, care +- must be taken to ensure that unintended interactive features are not enabled. "Secure" mode for the +- pager may be enabled automatically as describe above. Setting SYSTEMD_PAGERSECURE=0 +- or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note +- that if the $SYSTEMD_PAGER or $PAGER variables are to be +- honoured, $SYSTEMD_PAGERSECURE must be set too. It might be reasonable to completely +- disable the pager using instead. ++ project='die-net'>pkexec1, the ++ pager becomes a security boundary. Care must be taken that only programs with strictly limited ++ functionality are used as pagers, and unintended interactive features like opening or creation of new ++ files or starting of subprocesses are not allowed. "Secure mode" for the pager may be enabled as ++ described below, if the pager supports that (most pagers are not written in a way ++ that takes this into consideration). It is recommended to either explicitly enable "secure mode" or to ++ completely disable the pager using or PAGER=cat when ++ allowing untrusted users to execute commands with elevated privileges. ++ ++ This option takes a boolean argument. When set to true, the "secure mode" of the pager is ++ enabled. In "secure mode", will be set when invoking the pager, which ++ instructs the pager to disable commands that open or create new files or start new subprocesses. ++ Currently only less1 is known ++ to understand this variable and implement "secure mode". ++ ++ When set to false, no limitation is placed on the pager. Setting ++ SYSTEMD_PAGERSECURE=0 or not removing it from the inherited environment may allow ++ the user to invoke arbitrary commands. ++ ++ When $SYSTEMD_PAGERSECURE is not set, systemd tools attempt to automatically ++ figure out if "secure mode" should be enabled and whether the pager supports it. "Secure mode" is ++ enabled if the effective UID is not the same as the owner of the login session, see ++ geteuid2 ++ and ++ sd_pid_get_owner_uid3. ++ In this case, SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to ++ implement "secure mode" will not be used at all. ++ ++ Note that if the $SYSTEMD_PAGER or $PAGER variables are to ++ be honoured, $SYSTEMD_PAGERSECURE must be set too. ++ + + + diff --git a/1344-pager-also-check-for-SUDO_UID.patch b/1344-pager-also-check-for-SUDO_UID.patch new file mode 100644 index 0000000..3e2dd1e --- /dev/null +++ b/1344-pager-also-check-for-SUDO_UID.patch @@ -0,0 +1,132 @@ +From da56a9f1ec27bdf37928e53f90920a6f452cea51 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 6 May 2025 14:29:02 +0200 +Subject: [PATCH] pager: also check for $SUDO_UID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This returns to the original approach proposed in +https://github.com/systemd/systemd/pull/17270. After review, the approach was +changed to use sd_pid_get_owner_uid() instead. Back then, when running in a +typical graphical session, sd_pid_get_owner_uid() would usually return the user +UID, and when running under sudo, geteuid() would return 0, so we'd trigger the +secure path. + +sudo may allocate a new session if is invoked outside of a session (depending +on the PAM config). Since nowadays desktop environments usually start the user +shell through user units, the typical shell in a terminal emulator is not part +of a session, and when sudo is invoked, a new session is allocated, and +sd_pid_get_owner_uid() returns 0 too. Technically, the code still works as +documented in the man page, but in the common case, it doesn't do the expected +thing. + +$ build/test-sd-login |& rg 'get_(owner_uid|cgroup|session)' +sd_pid_get_session(0) → No data available +sd_pid_get_owner_uid(0) → 1000 +sd_pid_get_cgroup(0) → /user.slice/user-1000.slice/user@1000.service/app.slice/app-ghostty-transient-5088.scope/surfaces/556FAF50BA40.scope + +$ sudo build/test-sd-login |& rg 'get_(owner_uid|cgroup|session)' +sd_pid_get_session(0) → c289 +sd_pid_get_owner_uid(0) → 0 +sd_pid_get_cgroup(0) → /user.slice/user-0.slice/session-c289.scope + +I think it's worth checking for sudo because it is a common case used by users. +There obviously are other mechanims, so the man page is extended to say that +only some common mechanisms are supported, and to (again) recommend setting +SYSTEMD_LESSSECURE explicitly. The other option would be to set "secure mode" +by default. But this would create an inconvenience for users doing the right +thing, running systemctl and other tools directly, because then they can't run +privileged commands from the pager, e.g. to save the output to a file. (Or the +user would need to explicitly set SYSTEMD_LESSSECURE. One option would be to +set it always in the environment and to rely on sudo and other tools stripping +it from the environment before running privileged code. But that is also fairly +fragile and it obviously relies on the user doing a complicated setup to +support a fairly common use case. I think this decreases usability of the +system quite a bit. I don't think we should build solutions that work in +priniciple, but are painfully inconvenient in common cases.) + +Fixes https://yeswehack.com/vulnerability-center/reports/346802. + +Also see https://github.com/polkit-org/polkit/pull/562, which adds support for +$SUDO_UID/$SUDO_GID to pkexec. + +(cherry picked from commit cd93478af8b9dc69478d5667f113b67d175090fa) + +Resolves: RHEL-102941 +--- + man/common-variables.xml | 13 ++++++++++--- + src/shared/pager.c | 29 +++++++++++++++++++---------- + 2 files changed, 29 insertions(+), 13 deletions(-) + +diff --git a/man/common-variables.xml b/man/common-variables.xml +index d6de5ed059..9a45d4d6f2 100644 +--- a/man/common-variables.xml ++++ b/man/common-variables.xml +@@ -177,9 +177,16 @@ + enabled if the effective UID is not the same as the owner of the login session, see + geteuid2 + and +- sd_pid_get_owner_uid3. +- In this case, SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to +- implement "secure mode" will not be used at all. ++ sd_pid_get_owner_uid3, ++ or when running under ++ sudo8 or similar ++ tools ($SUDO_UID is set ++ It is recommended for other tools to set and check $SUDO_UID as appropriate, ++ treating it is a common interface.). In those cases, ++ SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to implement ++ "secure mode" will not be used at all. Note that this autodetection only covers the most common ++ mechanisms to elevate privileges and is intended as convenience. It is recommended to explicitly set ++ $SYSTEMD_PAGERSECURE or disable the pager. + + Note that if the $SYSTEMD_PAGER or $PAGER variables are to + be honoured, $SYSTEMD_PAGERSECURE must be set too. +diff --git a/src/shared/pager.c b/src/shared/pager.c +index dc717cd1fe..41a0b097cd 100644 +--- a/src/shared/pager.c ++++ b/src/shared/pager.c +@@ -83,6 +83,22 @@ static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) { + return r; + } + ++static bool running_with_escalated_privileges(void) { ++ int r; ++ ++ if (getenv("SUDO_UID")) ++ return true; ++ ++ uid_t uid; ++ r = sd_pid_get_owner_uid(0, &uid); ++ if (r < 0) { ++ log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m"); ++ return true; ++ } ++ ++ return uid != geteuid(); ++} ++ + void pager_open(PagerFlags flags) { + _cleanup_close_pair_ int fd[2] = { -1, -1 }, exe_name_pipe[2] = { -1, -1 }; + _cleanup_strv_free_ char **pager_args = NULL; +@@ -178,16 +194,9 @@ void pager_open(PagerFlags flags) { + * know to be good. */ + int use_secure_mode = getenv_bool_secure("SYSTEMD_PAGERSECURE"); + bool trust_pager = use_secure_mode >= 0; +- if (use_secure_mode == -ENXIO) { +- uid_t uid; +- +- r = sd_pid_get_owner_uid(0, &uid); +- if (r < 0) +- log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m"); +- +- use_secure_mode = r < 0 || uid != geteuid(); +- +- } else if (use_secure_mode < 0) { ++ if (use_secure_mode == -ENXIO) ++ use_secure_mode = running_with_escalated_privileges(); ++ else if (use_secure_mode < 0) { + log_warning_errno(use_secure_mode, "Unable to parse $SYSTEMD_PAGERSECURE, assuming true: %m"); + use_secure_mode = true; + } diff --git a/1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch b/1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch new file mode 100644 index 0000000..8f48c30 --- /dev/null +++ b/1345-hwdb-make-three-more-hwdb-files-parsed-by-parse_hwdb.patch @@ -0,0 +1,175 @@ +From 395d46b8650031be8d54d5a222fa8e2619f0b6a2 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 16 Jan 2026 23:50:35 +0900 +Subject: [PATCH] hwdb: make three more hwdb files parsed by parse_hwdb.py + +This also makes 70-lights.hwdb installed. The file was introduced by +106f64cbd66b8aa76333c3f11177f53e79e2cd82, but never installed. + +Moreover, this makes the parser also check bluetooth modalias patterns. + +(cherry picked from commit 3da9b65b304836c2c8b1812a8c328f0ce45b18f7) + +Resolves: RHEL-180937 +--- + hwdb.d/20-dmi-id.hwdb | 10 +++++----- + hwdb.d/70-lights.hwdb | 8 ++++---- + hwdb.d/meson.build | 5 +++-- + hwdb.d/parse_hwdb.py | 28 +++++++++++++++++++++++----- + 4 files changed, 35 insertions(+), 16 deletions(-) + +diff --git a/hwdb.d/20-dmi-id.hwdb b/hwdb.d/20-dmi-id.hwdb +index 905d6923bb..50fc1d21a6 100644 +--- a/hwdb.d/20-dmi-id.hwdb ++++ b/hwdb.d/20-dmi-id.hwdb +@@ -9,7 +9,7 @@ dmi:*:svnSystemmanufacturer:* + dmi:*:svnSystemManufacturer:* + dmi:*:svnTobefilledbyO.E.M.:* + dmi:*:svnToBeFilledByO.E.M.:* +- ID_SYS_VENDOR_IS_RUBBISH=1 ++ ID_SYS_VENDOR_IS_RUBBISH=1 + + dmi:*:pnDefaultstring:* + dmi:*:pnN/A:* +@@ -21,13 +21,13 @@ dmi:*:pnSystemname:* + dmi:*:pnSystemName:* + dmi:*:pnTobefilledbyO.E.M.:* + dmi:*:pnToBeFilledByO.E.M.:* +- ID_PRODUCT_NAME_IS_RUBBISH=1 ++ ID_PRODUCT_NAME_IS_RUBBISH=1 + + # Fix "Lenovo" capitalization in /sys/class/dmi/id/sys_vendor + dmi:bvnLENOVO* +- ID_SYSFS_ATTRIBUTE_MODEL=product_version +- ID_VENDOR_FROM_DATABASE=Lenovo ++ ID_SYSFS_ATTRIBUTE_MODEL=product_version ++ ID_VENDOR_FROM_DATABASE=Lenovo + + # Microsoft Surface 1's chassis type + dmi:bvnMicrosoft Corporation*:pvrSurface with Windows 8 Pro* +- ID_CHASSIS=tablet ++ ID_CHASSIS=tablet +diff --git a/hwdb.d/70-lights.hwdb b/hwdb.d/70-lights.hwdb +index a7753710ed..af56968abd 100644 +--- a/hwdb.d/70-lights.hwdb ++++ b/hwdb.d/70-lights.hwdb +@@ -26,11 +26,11 @@ + # Logitech + ################ + # Litra Beam +-bluetooth:v046dpc901* +-usb:v046dpc901* ++bluetooth:v046DpC901* ++usb:v046DpC901* + ID_AV_LIGHTS=1 + + # Litra Glow +-bluetooth:v046dpc900* +-usb:v046dpc900* ++bluetooth:v046DpC900* ++usb:v046DpC900* + ID_AV_LIGHTS=1 +diff --git a/hwdb.d/meson.build b/hwdb.d/meson.build +index e95ccda8c7..0f24f3095c 100644 +--- a/hwdb.d/meson.build ++++ b/hwdb.d/meson.build +@@ -5,7 +5,6 @@ + # So we don't "test" them. + hwdb_files_notest = files( + 'README', +- '20-dmi-id.hwdb', + '20-pci-vendor-model.hwdb', + '20-pci-classes.hwdb', + '20-usb-vendor-model.hwdb', +@@ -15,10 +14,11 @@ hwdb_files_notest = files( + '20-bluetooth-vendor-product.hwdb', + '20-acpi-vendor.hwdb', + '20-OUI.hwdb', +- '20-net-ifname.hwdb', + '20-vmbus-class.hwdb') + + hwdb_files_test = files( ++ '20-dmi-id.hwdb', ++ '20-net-ifname.hwdb', + '60-autosuspend.hwdb', + '60-autosuspend-fingerprint-reader.hwdb', + '60-evdev.hwdb', +@@ -31,6 +31,7 @@ hwdb_files_test = files( + '70-cameras.hwdb', + '70-hardware-wallets.hwdb', + '70-joystick.hwdb', ++ '70-lights.hwdb', + '70-maker-tools.hwdb', + '70-mouse.hwdb', + '70-pda.hwdb', +diff --git a/hwdb.d/parse_hwdb.py b/hwdb.d/parse_hwdb.py +index 9a599e735c..668734b237 100755 +--- a/hwdb.d/parse_hwdb.py ++++ b/hwdb.d/parse_hwdb.py +@@ -106,6 +106,7 @@ GENERAL_MATCHES = {'acpi', + 'vmbus', + 'OUI', + 'ieee1394', ++ 'dmi', + } + + def upperhex_word(length): +@@ -200,6 +201,16 @@ def property_grammar(): + ('ID_INFRARED_CAMERA', Or((Literal('0'), Literal('1')))), + ('ID_CAMERA_DIRECTION', Or(('front', 'rear'))), + ('SOUND_FORM_FACTOR', Or(('internal', 'webcam', 'speaker', 'headphone', 'headset', 'handset', 'microphone'))), ++ ('ID_SYS_VENDOR_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_PRODUCT_NAME_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_PRODUCT_VERSION_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_BOARD_VERSION_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_PRODUCT_SKU_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_CHASSIS_ASSET_TAG_IS_RUBBISH', Or((Literal('0'), Literal('1')))), ++ ('ID_CHASSIS', name_literal), ++ ('ID_SYSFS_ATTRIBUTE_MODEL', name_literal), ++ ('ID_NET_NAME_FROM_DATABASE', name_literal), ++ ('ID_NET_NAME_INCLUDE_DOMAIN', Or((Literal('0'), Literal('1')))), + ) + fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') + for name, val in props] +@@ -242,8 +253,10 @@ def check_matches(groups): + + # This is a partial check. The other cases could be also done, but those + # two are most commonly wrong. +- grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', +- 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*', ++ grammars = { ++ 'bluetooth' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', ++ 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', ++ 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*', + } + + for match in matches: +@@ -252,12 +265,12 @@ def check_matches(groups): + if gr: + # we check this first to provide an easy error message + if rest[-1] not in '*:': +- error('pattern {} does not end with "*" or ":"', match) ++ error('Pattern {} does not end with "*" or ":"', match) + + try: + gr.parseString(rest) + except ParseBaseException as e: +- error('Pattern {!r} is invalid: {}', rest, e) ++ error('Pattern {} is invalid: {}', match, e) + continue + + matches.sort() +@@ -339,7 +352,12 @@ def print_summary(fname, groups): + error(f'{fname}: no matches or props') + + if __name__ == '__main__': +- args = sys.argv[1:] or sorted(glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb')) ++ args = sys.argv[1:] or sorted( ++ [ ++ os.path.dirname(sys.argv[0]) + '/20-dmi-id.hwdb', ++ os.path.dirname(sys.argv[0]) + '/20-net-ifname.hwdb', ++ ] + glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb') ++ ) + + for fname in args: + groups = parse(fname) diff --git a/1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch b/1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch new file mode 100644 index 0000000..36097c9 --- /dev/null +++ b/1346-nss-systemd-avoid-ELF-TLS-for-recursion-guard.patch @@ -0,0 +1,109 @@ +From b68c06df98888614397997bb3710aea976fb7473 Mon Sep 17 00:00:00 2001 +From: Roman Vinogradov +Date: Thu, 11 Jun 2026 14:21:55 +0000 +Subject: [PATCH] nss-systemd: avoid ELF TLS for recursion guard + +libnss_systemd currently uses a thread_local recursion guard to +avoid re-entering nss-systemd during NSS lookups. +Since libnss_systemd.so.2 is loaded lazily by glibc, accessing ELF TLS +may trigger dynamic TLS allocation in __tls_get_addr(). Under allocation +failure conditions, glibc terminates the process from the dynamic loader +instead of allowing the NSS module to return a normal failure. +Replace the recursion guard with POSIX thread-specific data to preserve the +same per-thread semantics while avoiding ELF TLS in the NSS module. +Note that pthread_setspecific() may still allocate internally on first use +per thread. The key improvement is that any such failure is returned +as a normal error code rather than terminating the process from inside +the dynamic loader. + +Related to: #42559 +(cherry picked from commit 19bd80e29a02b4f8c9543370eb4a16c014d497f3) + +Resolves: RHEL-193714 +--- + src/nss-systemd/nss-systemd.c | 56 +++++++++++++++++++++++++++++++---- + 1 file changed, 50 insertions(+), 6 deletions(-) + +diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c +index 1d6e25399f..1cb36a153a 100644 +--- a/src/nss-systemd/nss-systemd.c ++++ b/src/nss-systemd/nss-systemd.c +@@ -1057,28 +1057,72 @@ enum nss_status _nss_systemd_initgroups_dyn( + return any ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND; + } + +-static thread_local unsigned _blocked = 0; ++/* Note that we intentionally use POSIX thread-specific data instead of a plain thread_local variable. ++ * A thread_local in this lazily-loaded DSO uses a dynamic TLS model by default and may require ++ * a dynamic TLS allocation. If that allocation fails, glibc calls _exit() from the dynamic linker, ++ * making the failure unrecoverable. Using pthread_key_t avoids ELF TLS entirely and lets any such ++ * failure propagate as a normal error instead of terminating the process. */ ++static pthread_once_t nss_blocked_key_once = PTHREAD_ONCE_INIT; ++static pthread_key_t nss_blocked_key; ++static int nss_blocked_key_error; ++ ++static void nss_blocked_key_init(void) { ++ /* NULL destructor: the per-thread value is a plain integer counter encoded as void*, ++ * not a heap allocation, so nothing needs to be freed at thread exit. ++ * No pthread_key_delete: this library is linked with -z nodelete and always opened with ++ * RTLD_NODELETE, so it is never unloaded and the key exists for the process lifetime. */ ++ nss_blocked_key_error = pthread_key_create(&nss_blocked_key, NULL); ++} ++ ++static int nss_blocked_key_ensure(void) { ++ int r; ++ ++ r = pthread_once(&nss_blocked_key_once, nss_blocked_key_init); ++ if (r != 0) ++ return -r; ++ ++ if (nss_blocked_key_error != 0) ++ return -nss_blocked_key_error; ++ ++ return 0; ++} + + _public_ int _nss_systemd_block(bool b) { ++ int r; ++ uintptr_t blocked; ++ ++ r = nss_blocked_key_ensure(); ++ if (r < 0) ++ return r; ++ ++ blocked = (uintptr_t) pthread_getspecific(nss_blocked_key); + + /* This blocks recursively: it's blocked for as many times this function is called with `true` until + * it is called an equal time with `false`. */ + + if (b) { +- if (_blocked >= UINT_MAX) ++ if (blocked >= UINTPTR_MAX) + return -EOVERFLOW; + +- _blocked++; ++ blocked++; + } else { +- if (_blocked <= 0) ++ if (blocked == 0) + return -EOVERFLOW; + +- _blocked--; ++ blocked--; + } + ++ r = pthread_setspecific(nss_blocked_key, (void*) blocked); ++ /* Ignore failure on the unblock path: callers may assert on it. */ ++ if (r != 0 && b) ++ return -r; ++ + return b; /* Return what is passed in, i.e. the new state from the PoV of the caller */ + } + + _public_ bool _nss_systemd_is_blocked(void) { +- return _blocked > 0; ++ if (nss_blocked_key_ensure() < 0) ++ return false; ++ ++ return (uintptr_t) pthread_getspecific(nss_blocked_key) > 0; + } diff --git a/1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch b/1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch new file mode 100644 index 0000000..93f40f1 --- /dev/null +++ b/1347-udev-builtin-net-id-print-cescaped-bad-attributes.patch @@ -0,0 +1,60 @@ +From 62099c992b6e5887ce5c0bb3a46113544ced9d5b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 11 Mar 2026 11:27:48 +0100 +Subject: [PATCH] udev-builtin-net-id: print cescaped bad attributes + +Follow-up for 16325b35fa6ecb25f66534a562583ce3b96d52f3. Let's +log those bad value to make it easier to figure out why things +are not working if we reject an attribute. + +(cherry picked from commit 7c4047957ef58744ecfad6d277f7c45d430f6d70) + +Resolves: RHEL-180934 +--- + src/udev/udev-builtin-net_id.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 6bb6465832..8003f48eba 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -27,6 +27,7 @@ + #include "device-private.h" + #include "device-util.h" + #include "dirent-util.h" ++#include "escape.h" + #include "ether-addr-util.h" + #include "fd-util.h" + #include "fileio.h" +@@ -44,6 +45,12 @@ + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) + ++static int log_invalid_device_attr(sd_device *dev, const char *attr, const char *value) { ++ _cleanup_free_ char *escaped = cescape(value); ++ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), ++ "Invalid %s value '%s'.", attr, strnull(escaped)); ++} ++ + typedef enum NetNameType { + NET_UNDEF, + NET_PCI, +@@ -701,8 +708,7 @@ static int names_platform(sd_device *dev, NetNames *names, bool test) { + return -EINVAL; + + if (!in_charset(vendor, validchars)) +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENOENT), +- "Platform vendor contains invalid characters: %s", vendor); ++ return log_invalid_device_attr(dev, "platform vendor", vendor); + + ascii_strlower(vendor); + +@@ -1191,7 +1197,7 @@ static int get_link_info(sd_device *dev, LinkInfo *info) { + r = device_get_sysattr_value_filtered(dev, "phys_port_name", &info->phys_port_name); + if (r >= 0) { + if (!utf8_is_valid(info->phys_port_name) || string_has_cc(info->phys_port_name, /* ok= */ NULL)) +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid phys_port_name"); ++ return log_invalid_device_attr(dev, "phys_port_name", info->phys_port_name); + + /* Check if phys_port_name indicates virtual device representor */ + (void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id); diff --git a/1348-udev-drop-redundant-checks.patch b/1348-udev-drop-redundant-checks.patch new file mode 100644 index 0000000..20d9fd6 --- /dev/null +++ b/1348-udev-drop-redundant-checks.patch @@ -0,0 +1,37 @@ +From 010019fa40cb709ea8b111c04301d9a5e7dbbde0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 12 Mar 2026 07:16:46 +0900 +Subject: [PATCH] udev: drop redundant checks + +This partially reverts 16325b35fa6ecb25f66534a562583ce3b96d52f3, +as bad characters are already filtered. + +(cherry picked from commit c5a04f59d912fb2c3451994279dea3ae3064f6c7) + +Resolves: RHEL-180934 +--- + src/udev/udev-builtin-net_id.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 8003f48eba..de2c1fe782 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -40,7 +40,6 @@ + #include "strv.h" + #include "strxcpyx.h" + #include "udev-builtin.h" +-#include "utf8.h" + + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) +@@ -1196,9 +1195,6 @@ static int get_link_info(sd_device *dev, LinkInfo *info) { + + r = device_get_sysattr_value_filtered(dev, "phys_port_name", &info->phys_port_name); + if (r >= 0) { +- if (!utf8_is_valid(info->phys_port_name) || string_has_cc(info->phys_port_name, /* ok= */ NULL)) +- return log_invalid_device_attr(dev, "phys_port_name", info->phys_port_name); +- + /* Check if phys_port_name indicates virtual device representor */ + (void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id); + } diff --git a/1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch b/1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch new file mode 100644 index 0000000..b1d1567 --- /dev/null +++ b/1349-Revert-udev-builtin-net-id-print-cescaped-bad-attrib.patch @@ -0,0 +1,51 @@ +From 5553702cddcaf257e8ebee9ea3d3cdf035127d61 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 12 Mar 2026 07:14:44 +0900 +Subject: [PATCH] Revert "udev-builtin-net-id: print cescaped bad attributes" + +This reverts commit 7c4047957ef58744ecfad6d277f7c45d430f6d70. + +This is not necessary, as bad characters are already filtered. + +(cherry picked from commit c6ea72e39a8d829b1bd65f15f6dd7d1c2b6d04c3) + +Resolves: RHEL-180934 +--- + src/udev/udev-builtin-net_id.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index de2c1fe782..d2482f5579 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -27,7 +27,6 @@ + #include "device-private.h" + #include "device-util.h" + #include "dirent-util.h" +-#include "escape.h" + #include "ether-addr-util.h" + #include "fd-util.h" + #include "fileio.h" +@@ -44,12 +43,6 @@ + #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) + #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) + +-static int log_invalid_device_attr(sd_device *dev, const char *attr, const char *value) { +- _cleanup_free_ char *escaped = cescape(value); +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), +- "Invalid %s value '%s'.", attr, strnull(escaped)); +-} +- + typedef enum NetNameType { + NET_UNDEF, + NET_PCI, +@@ -707,7 +700,8 @@ static int names_platform(sd_device *dev, NetNames *names, bool test) { + return -EINVAL; + + if (!in_charset(vendor, validchars)) +- return log_invalid_device_attr(dev, "platform vendor", vendor); ++ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENOENT), ++ "Platform vendor contains invalid characters: %s", vendor); + + ascii_strlower(vendor); + diff --git a/systemd.spec b/systemd.spec index c4599f4..01d9a62 100644 --- a/systemd.spec +++ b/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 - 252-72 +- man: reword the description of "secure pager" handling (RHEL-102941) +- pager: also check for $SUDO_UID (RHEL-102941) +- hwdb: make three more hwdb files parsed by parse_hwdb.py (RHEL-180937) +- nss-systemd: avoid ELF TLS for recursion guard (RHEL-193714) +- udev-builtin-net-id: print cescaped bad attributes (RHEL-180934) +- udev: drop redundant checks (RHEL-180934) +- Revert "udev-builtin-net-id: print cescaped bad attributes" (RHEL-180934) + * Tue Jun 09 2026 systemd maintenance team - 252-71 - Do not build efi stub on i686 anymore (RHEL-176073)