From 73b8a454b85e8e54bfdf21865bb8d1de819c423f Mon Sep 17 00:00:00 2001 From: eabdullin Date: Mon, 9 Jun 2025 19:16:28 +0000 Subject: [PATCH] import UBI glibc-2.28-251.el8_10.22 --- SOURCES/glibc-RHEL-71921.patch | 188 ++++++++++++++++++ SOURCES/glibc-RHEL-76211.patch | 69 +++++++ SOURCES/glibc-RHEL-76387.patch | 32 ++++ SOURCES/glibc-RHEL-86018-1.patch | 194 +++++++++++++++++++ SOURCES/glibc-RHEL-86018-2.patch | 29 +++ SOURCES/glibc-RHEL-88813.patch | 31 +++ SOURCES/glibc-RHEL-92685-1.patch | 23 +++ SOURCES/glibc-RHEL-92685-2.patch | 52 +++++ SOURCES/glibc-RHEL-92685-3.patch | 86 +++++++++ SOURCES/glibc-RHEL-92685-4.patch | 41 ++++ SOURCES/glibc-RHEL-92685-5.patch | 56 ++++++ SOURCES/glibc-RHEL-92685-6.patch | 159 ++++++++++++++++ SOURCES/glibc-RHEL-92685-7.patch | 42 +++++ SOURCES/glibc-RHEL-92685-8.patch | 105 +++++++++++ SOURCES/glibc-RHEL-92685-9.patch | 315 +++++++++++++++++++++++++++++++ SPECS/glibc.spec | 36 +++- 16 files changed, 1457 insertions(+), 1 deletion(-) create mode 100644 SOURCES/glibc-RHEL-71921.patch create mode 100644 SOURCES/glibc-RHEL-76211.patch create mode 100644 SOURCES/glibc-RHEL-76387.patch create mode 100644 SOURCES/glibc-RHEL-86018-1.patch create mode 100644 SOURCES/glibc-RHEL-86018-2.patch create mode 100644 SOURCES/glibc-RHEL-88813.patch create mode 100644 SOURCES/glibc-RHEL-92685-1.patch create mode 100644 SOURCES/glibc-RHEL-92685-2.patch create mode 100644 SOURCES/glibc-RHEL-92685-3.patch create mode 100644 SOURCES/glibc-RHEL-92685-4.patch create mode 100644 SOURCES/glibc-RHEL-92685-5.patch create mode 100644 SOURCES/glibc-RHEL-92685-6.patch create mode 100644 SOURCES/glibc-RHEL-92685-7.patch create mode 100644 SOURCES/glibc-RHEL-92685-8.patch create mode 100644 SOURCES/glibc-RHEL-92685-9.patch diff --git a/SOURCES/glibc-RHEL-71921.patch b/SOURCES/glibc-RHEL-71921.patch new file mode 100644 index 0000000..605e645 --- /dev/null +++ b/SOURCES/glibc-RHEL-71921.patch @@ -0,0 +1,188 @@ +commit aa3d7bd5299b33bffc118aa618b59bfa66059bcb +Author: Florian Weimer +Date: Thu Feb 13 21:56:52 2025 +0100 + + elf: Keep using minimal malloc after early DTV resize (bug 32412) + + If an auditor loads many TLS-using modules during startup, it is + possible to trigger DTV resizing. Previously, the DTV was marked + as allocated by the main malloc afterwards, even if the minimal + malloc was still in use. With this change, _dl_resize_dtv marks + the resized DTV as allocated with the minimal malloc. + + The new test reuses TLS-using modules from other auditing tests. + + Reviewed-by: DJ Delorie + +Conflicts: + elf/Makefile + (Add $(libdl), Usual conflicts due to test backport differences.) + +diff -Nrup a/elf/Makefile b/elf/Makefile +--- a/elf/Makefile 2025-05-06 18:12:04.588668410 -0400 ++++ b/elf/Makefile 2025-05-12 16:35:57.997071294 -0400 +@@ -333,6 +333,7 @@ tests += \ + tst-align2 \ + tst-audit-tlsdesc \ + tst-audit-tlsdesc-dlopen \ ++ tst-audit-tlsdesc-dlopen2 \ + tst-audit1 \ + tst-audit11 \ + tst-audit12 \ +@@ -694,6 +695,7 @@ modules-names = \ + tst-auditmanymod8 \ + tst-auditmanymod9 \ + tst-auditmod-tlsdesc \ ++ tst-auditmod-tlsdesc2 \ + tst-auditmod1 \ + tst-auditmod9a \ + tst-auditmod9b \ +@@ -1383,6 +1385,7 @@ $(objpfx)tst-tlsalign: $(objpfx)tst-tlsa + $(objpfx)tst-nodelete-opened.out: $(objpfx)tst-nodelete-opened-lib.so + $(objpfx)tst-nodelete-opened: $(libdl) + $(objpfx)tst-noload: $(libdl) ++$(objpfx)tst-auditmod-tlsdesc2.so: $(libdl) + + $(objpfx)tst-tlsalign-extern: $(objpfx)tst-tlsalign-vars.o + $(objpfx)tst-tlsalign-extern-static: $(objpfx)tst-tlsalign-vars.o +@@ -2736,6 +2739,10 @@ tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpf + $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so + tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so + ++$(objpfx)tst-audit-tlsdesc-dlopen2: $(shared-thread-library) $(libdl) ++$(objpfx)tst-audit-tlsdesc-dlopen2.out: $(objpfx)tst-auditmod-tlsdesc2.so \ ++ $(patsubst %, $(objpfx)%.so, $(tlsmod17a-modules)) ++tst-audit-tlsdesc-dlopen2-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc2.so + + $(objpfx)tst-dlmopen-twice: $(libdl) + $(objpfx)tst-dlmopen-twice.out: \ +diff -Nrup a/elf/dl-tls.c b/elf/dl-tls.c +--- a/elf/dl-tls.c 2025-05-06 18:12:04.585668394 -0400 ++++ b/elf/dl-tls.c 2025-05-07 08:21:56.363042714 -0400 +@@ -529,6 +529,13 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_m + if (newp == NULL) + oom (); + memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t)); ++#ifdef SHARED ++ /* Auditors can trigger a DTV resize event while the full malloc ++ is not yet in use. Mark the new DTV allocation as the ++ initial allocation. */ ++ if (!__rtld_malloc_is_complete ()) ++ GL(dl_initial_dtv) = &newp[1]; ++#endif + } + else + { +diff -Nrup a/elf/tst-audit-tlsdesc-dlopen2.c b/elf/tst-audit-tlsdesc-dlopen2.c +--- a/elf/tst-audit-tlsdesc-dlopen2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/elf/tst-audit-tlsdesc-dlopen2.c 2025-05-07 08:21:56.363042714 -0400 +@@ -0,0 +1,46 @@ ++/* Loading TLS-using modules from auditors (bug 32412). Main program. ++ Copyright (C) 2021-2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ puts ("info: start of main program"); ++ ++ /* Load TLS-using modules, to trigger DTV resizing. The dynamic ++ linker will load them again (requiring their own TLS) because the ++ dlopen calls from the auditor were in the auditing namespace. */ ++ for (int i = 1; i <= 19; ++i) ++ { ++ char dso[30]; ++ snprintf (dso, sizeof (dso), "tst-tlsmod17a%d.so", i); ++ char sym[30]; ++ snprintf (sym, sizeof(sym), "tlsmod17a%d", i); ++ ++ void *handle = xdlopen (dso, RTLD_LAZY); ++ int (*func) (void) = xdlsym (handle, sym); ++ /* Trigger TLS allocation. */ ++ func (); ++ } ++ ++ return 0; ++} ++ ++#include +diff -Nrup a/elf/tst-auditmod-tlsdesc2.c b/elf/tst-auditmod-tlsdesc2.c +--- a/elf/tst-auditmod-tlsdesc2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/elf/tst-auditmod-tlsdesc2.c 2025-05-07 08:21:56.363042714 -0400 +@@ -0,0 +1,59 @@ ++/* Loading TLS-using modules from auditors (bug 32412). Audit module. ++ Copyright (C) 2021-2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ /* Open some modules, to trigger DTV resizing before the switch to ++ the main malloc. */ ++ for (int i = 1; i <= 19; ++i) ++ { ++ char dso[30]; ++ snprintf (dso, sizeof (dso), "tst-tlsmod17a%d.so", i); ++ char sym[30]; ++ snprintf (sym, sizeof(sym), "tlsmod17a%d", i); ++ ++ void *handle = dlopen (dso, RTLD_LAZY); ++ if (handle == NULL) ++ { ++ printf ("error: dlmopen from auditor: %s\n", dlerror ()); ++ fflush (stdout); ++ _exit (1); ++ } ++ int (*func) (void) = dlsym (handle, sym); ++ if (func == NULL) ++ { ++ printf ("error: dlsym from auditor: %s\n", dlerror ()); ++ fflush (stdout); ++ _exit (1); ++ } ++ /* Trigger TLS allocation. */ ++ func (); ++ } ++ ++ puts ("info: TLS-using modules loaded from auditor"); ++ fflush (stdout); ++ ++ return LAV_CURRENT; ++} diff --git a/SOURCES/glibc-RHEL-76211.patch b/SOURCES/glibc-RHEL-76211.patch new file mode 100644 index 0000000..770d8c7 --- /dev/null +++ b/SOURCES/glibc-RHEL-76211.patch @@ -0,0 +1,69 @@ +commit 1493622f4f9048ffede3fbedb64695efa49d662a +Author: H.J. Lu +Date: Mon Aug 28 12:08:14 2023 -0700 + + x86: Check the lower byte of EAX of CPUID leaf 2 [BZ #30643] + + The old Intel software developer manual specified that the low byte of + EAX of CPUID leaf 2 returned 1 which indicated the number of rounds of + CPUDID leaf 2 was needed to retrieve the complete cache information. The + newer Intel manual has been changed to that it should always return 1 + and be ignored. If the lower byte isn't 1, CPUID leaf 2 can't be used. + In this case, we ignore CPUID leaf 2 and use CPUID leaf 4 instead. If + CPUID leaf 4 doesn't contain the cache information, cache information + isn't available at all. This addresses BZ #30643. + +diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h +index 5ddb35c9d9..87486054f9 100644 +--- a/sysdeps/x86/dl-cacheinfo.h ++++ b/sysdeps/x86/dl-cacheinfo.h +@@ -187,7 +187,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, + ++round; + } + /* There is no other cache information anywhere else. */ +- break; ++ return -1; + } + else + { +@@ -257,28 +257,23 @@ handle_intel (int name, const struct cpu_features *cpu_features) + + /* OK, we can use the CPUID instruction to get all info about the + caches. */ +- unsigned int cnt = 0; +- unsigned int max = 1; + long int result = 0; + bool no_level_2_or_3 = false; + bool has_level_2 = false; ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ __cpuid (2, eax, ebx, ecx, edx); + +- while (cnt++ < max) ++ /* The low byte of EAX of CPUID leaf 2 should always return 1 and it ++ should be ignored. If it isn't 1, use CPUID leaf 4 instead. */ ++ if ((eax & 0xff) != 1) ++ return intel_check_word (name, 0xff, &has_level_2, &no_level_2_or_3, ++ cpu_features); ++ else + { +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- __cpuid (2, eax, ebx, ecx, edx); +- +- /* The low byte of EAX in the first round contain the number of +- rounds we have to make. At least one, the one we are already +- doing. */ +- if (cnt == 1) +- { +- max = eax & 0xff; +- eax &= 0xffffff00; +- } ++ eax &= 0xffffff00; + + /* Process the individual registers' value. */ + result = intel_check_word (name, eax, &has_level_2, diff --git a/SOURCES/glibc-RHEL-76387.patch b/SOURCES/glibc-RHEL-76387.patch new file mode 100644 index 0000000..a838531 --- /dev/null +++ b/SOURCES/glibc-RHEL-76387.patch @@ -0,0 +1,32 @@ +commit 61c3450db96dce96ad2b24b4f0b548e6a46d68e5 +Author: Florian Weimer +Date: Tue Dec 17 18:12:03 2024 +0100 + + x86: Avoid integer truncation with large cache sizes (bug 32470) + + Some hypervisors report 1 TiB L3 cache size. This results + in some variables incorrectly getting zeroed, causing crashes + in memcpy/memmove because invariants are violated. + +Conflicts: + sysdeps/x86/dl-cacheinfo.h + (missing backport of commit 2d651eb9265d1366d7b9e881bfddd4 + ("x86: Move x86 processor cache info to cpu_features")) + +diff -Nrup a/sysdeps/x86/cacheinfo.h b/sysdeps/x86/cacheinfo.h +--- a/sysdeps/x86/cacheinfo.h 2025-04-09 11:11:06.532319998 -0400 ++++ b/sysdeps/x86/cacheinfo.h 2025-04-09 11:17:39.493355111 -0400 +@@ -388,11 +388,11 @@ init_cacheinfo (void) + : non_temporal_threshold); + + /* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8. */ +- unsigned int minimum_rep_movsb_threshold; ++ unsigned long int minimum_rep_movsb_threshold; + /* NB: The default REP MOVSB threshold is 4096 * (VEC_SIZE / 16) for + VEC_SIZE == 64 or 32. For VEC_SIZE == 16, the default REP MOVSB + threshold is 2048 * (VEC_SIZE / 16). */ +- unsigned int rep_movsb_threshold; ++ unsigned long int rep_movsb_threshold; + if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F) + && !CPU_FEATURE_PREFERRED_P (cpu_features, Prefer_No_AVX512)) + { diff --git a/SOURCES/glibc-RHEL-86018-1.patch b/SOURCES/glibc-RHEL-86018-1.patch new file mode 100644 index 0000000..1186217 --- /dev/null +++ b/SOURCES/glibc-RHEL-86018-1.patch @@ -0,0 +1,194 @@ +commit 9f0d2c0ee6c728643fcf9a4879e9f20f5e45ce5f +Author: Arjun Shankar +Date: Fri Oct 18 16:03:25 2024 +0200 + + libio: Fix a deadlock after fork in popen + + popen modifies its file handler book-keeping under a lock that wasn't + being taken during fork. This meant that a concurrent popen and fork + could end up copying the lock in a "locked" state into the fork child, + where subsequently calling popen would lead to a deadlock due to the + already (spuriously) held lock. + + This commit fixes the deadlock by appropriately taking the lock before + fork, and releasing/resetting it in the parent/child after the fork. + + A new test for concurrent popen and fork is also added. It consistently + hangs (and therefore fails via timeout) without the fix applied. + Reviewed-by: Florian Weimer + +Conflicts: + libio/Makefile + (Usual conflict when adding tests due to missing backports.) + posix/fork.c + (reworked due to file rename upstream and libpthread integration) + + +diff -Nrup a/libio/Makefile b/libio/Makefile +--- a/libio/Makefile 2025-04-23 15:51:08.439579602 -0400 ++++ b/libio/Makefile 2025-04-23 15:11:32.124866600 -0400 +@@ -62,7 +62,7 @@ tests = tst_swprintf tst_wprintf tst_sws + tst-memstream1 tst-memstream2 tst-memstream3 \ + tst-wmemstream1 tst-wmemstream2 tst-wmemstream3 \ + bug-memstream1 bug-wmemstream1 \ +- tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ ++ tst-setvbuf1 tst-popen-fork tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ + tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ + tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \ + tst-wfile-sync +diff -Nrup a/libio/iopopen.c b/libio/iopopen.c +--- a/libio/iopopen.c 2025-04-23 15:51:09.145583660 -0400 ++++ b/libio/iopopen.c 2025-04-23 15:07:45.167549822 -0400 +@@ -60,6 +60,26 @@ unlock (void *not_used) + } + #endif + ++/* These lock/unlock/resetlock functions are used during fork. */ ++ ++void ++_IO_proc_file_chain_lock (void) ++{ ++ _IO_lock_lock (proc_file_chain_lock); ++} ++ ++void ++_IO_proc_file_chain_unlock (void) ++{ ++ _IO_lock_unlock (proc_file_chain_lock); ++} ++ ++void ++_IO_proc_file_chain_resetlock (void) ++{ ++ _IO_lock_init (proc_file_chain_lock); ++} ++ + /* POSIX states popen shall ensure that any streams from previous popen() + calls that remain open in the parent process should be closed in the new + child process. +diff -Nrup a/libio/libioP.h b/libio/libioP.h +--- a/libio/libioP.h 2025-04-23 15:51:08.012577147 -0400 ++++ b/libio/libioP.h 2025-04-23 15:07:45.167549822 -0400 +@@ -423,6 +423,12 @@ libc_hidden_proto (_IO_list_resetlock) + extern void _IO_enable_locks (void) __THROW; + libc_hidden_proto (_IO_enable_locks) + ++/* Functions for operating popen's proc_file_chain_lock during fork. */ ++ ++extern void _IO_proc_file_chain_lock (void) __THROW attribute_hidden; ++extern void _IO_proc_file_chain_unlock (void) __THROW attribute_hidden; ++extern void _IO_proc_file_chain_resetlock (void) __THROW attribute_hidden; ++ + /* Default jumptable functions. */ + + extern int _IO_default_underflow (FILE *) __THROW; +diff -Nrup a/libio/tst-popen-fork.c b/libio/tst-popen-fork.c +--- a/libio/tst-popen-fork.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/libio/tst-popen-fork.c 2025-04-23 15:07:45.168549828 -0400 +@@ -0,0 +1,80 @@ ++/* Test concurrent popen and fork. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++static void ++popen_and_pclose (void) ++{ ++ FILE *f = popen ("true", "r"); ++ TEST_VERIFY_EXIT (f != NULL); ++ pclose (f); ++ return; ++} ++ ++static atomic_bool done = ATOMIC_VAR_INIT (0); ++ ++static void * ++popen_and_pclose_forever (__attribute__ ((unused)) ++ void *arg) ++{ ++ while (!atomic_load_explicit (&done, memory_order_acquire)) ++ popen_and_pclose (); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ ++ /* Repeatedly call popen in a loop during the entire test. */ ++ pthread_t t = xpthread_create (NULL, popen_and_pclose_forever, NULL); ++ ++ /* Repeatedly fork off and reap child processes one-by-one. ++ Each child calls popen once, then exits, leading to the possibility ++ that a child forks *during* our own popen call, thus inheriting any ++ intermediate popen state, possibly including lock state(s). */ ++ for (int i = 0; i < 100; i++) ++ { ++ int cpid = xfork (); ++ ++ if (cpid == 0) ++ { ++ popen_and_pclose (); ++ _exit (0); ++ } ++ else ++ xwaitpid (cpid, NULL, 0); ++ } ++ ++ /* Stop calling popen. */ ++ atomic_store_explicit (&done, 1, memory_order_release); ++ xpthread_join (t); ++ ++ return 0; ++} ++ ++#include +--- a/sysdeps/nptl/fork.c 2025-04-23 16:33:49.283403134 -0400 ++++ b/sysdeps/nptl/fork.c 2025-04-23 16:33:12.240190356 -0400 +@@ -65,6 +65,7 @@ __libc_fork (void) + not matter if fork was called from a signal handler. */ + if (multiple_threads) + { ++ _IO_proc_file_chain_lock (); + _IO_list_lock (); + + /* Acquire malloc locks. This needs to come last because fork +@@ -121,6 +122,7 @@ __libc_fork (void) + + /* Reset locks in the I/O code. */ + _IO_list_resetlock (); ++ _IO_proc_file_chain_resetlock (); + } + + /* Reset the lock the dynamic loader uses to protect its data. */ +@@ -142,6 +144,7 @@ __libc_fork (void) + + /* We execute this even if the 'fork' call failed. */ + _IO_list_unlock (); ++ _IO_proc_file_chain_unlock (); + } + + /* Run the handlers registered for the parent. */ diff --git a/SOURCES/glibc-RHEL-86018-2.patch b/SOURCES/glibc-RHEL-86018-2.patch new file mode 100644 index 0000000..5b3b7ca --- /dev/null +++ b/SOURCES/glibc-RHEL-86018-2.patch @@ -0,0 +1,29 @@ +commit 6a290b2895b77be839fcb7c44a6a9879560097ad +Author: Arjun Shankar +Date: Fri Oct 25 09:33:45 2024 +0200 + + libio: Correctly link tst-popen-fork against libpthread + + tst-popen-fork failed to build for Hurd due to not being linked with + libpthread. This commit fixes that. + + Tested with build-many-glibcs.py for i686-gnu. + + Reviewed-by: Florian Weimer + +Conflicts: + libio/Makefile + (Usual conflict when adding tests due to missing backports.) + +diff -Nrup a/libio/Makefile b/libio/Makefile +--- a/libio/Makefile 2025-04-23 16:41:58.028210552 -0400 ++++ b/libio/Makefile 2025-04-23 16:41:30.195050679 -0400 +@@ -67,6 +67,8 @@ tests = tst_swprintf tst_wprintf tst_sws + tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \ + tst-wfile-sync + ++$(objpfx)tst-popen-fork: $(shared-thread-library) ++ + tests-internal = tst-vtables tst-vtables-interposed + + ifeq (yes,$(build-shared)) diff --git a/SOURCES/glibc-RHEL-88813.patch b/SOURCES/glibc-RHEL-88813.patch new file mode 100644 index 0000000..f6330a6 --- /dev/null +++ b/SOURCES/glibc-RHEL-88813.patch @@ -0,0 +1,31 @@ +commit 268bb71e475d7e40fad83313be0eeb173e599c92 +Author: Stefan Liebler +Date: Fri Dec 14 09:50:53 2018 +0100 + + Add missing libnss_testX.so requirement for tst-nss-test3. + + Sometimes tst-nss-test3 fails with: + error: test-container.c:386: unable to open .../nss/libnss_test1.so for reading + + The test tst-nss-test3 which runs in a container needs + libnss_test[12].so. (see e.g. tst-nss-test3.script). + Before this test was moved from tests to tests-container variable, + the requirement was met. Thus this patch adds this requirement + also for tests in tests-container. + +Conflicts: + ChangeLog + (removed) + +diff -Nrup a/nss/Makefile b/nss/Makefile +--- a/nss/Makefile 2025-05-01 21:21:05.471995292 -0400 ++++ b/nss/Makefile 2025-05-01 21:19:15.440411065 -0400 +@@ -197,7 +197,7 @@ $(objpfx)/libnss_test_errno.so$(libnss_f + $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ + $(objpfx)/libnss_test_gai_hv2_canonname.so + $(make-link) +-$(patsubst %,$(objpfx)%.out,$(tests)) : \ ++$(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \ + $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \ + $(objpfx)/libnss_test2.so$(libnss_test2.so-version) \ + $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \ diff --git a/SOURCES/glibc-RHEL-92685-1.patch b/SOURCES/glibc-RHEL-92685-1.patch new file mode 100644 index 0000000..3200434 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-1.patch @@ -0,0 +1,23 @@ +commit 45caed9d67a00af917d8b5b88d4b5eb1225b7aef +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:53 2021 +0530 + + copy_and_spawn_sgid: Avoid double calls to close() + + If close() on infd and outfd succeeded, reset the fd numbers so that + we don't attempt to close them again. + + Reviewed-by: Arjun Shankar + +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index eec5371d5602aa29..9da5ba0c10bf6eee 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -169,6 +169,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid) + support_subprogram because we only want the program exit status, not the + contents. */ + ret = 0; ++ infd = outfd = -1; + + char * const args[] = {execname, child_id, NULL}; + diff --git a/SOURCES/glibc-RHEL-92685-2.patch b/SOURCES/glibc-RHEL-92685-2.patch new file mode 100644 index 0000000..7c625d1 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-2.patch @@ -0,0 +1,52 @@ +commit 6286cca2cb8389dcffec39238a8bf15ffea96396 +Author: Siddhesh Poyarekar +Date: Thu Jun 1 07:23:15 2023 -0400 + + support: Don't fail on fchown when spawning sgid processes + + In some cases (e.g. when podman creates user containers), the only other + group assigned to the executing user is nobody and fchown fails with it + because the group is not mapped. Do not fail the test in this case, + instead exit as unsupported. + + Reported-by: Frédéric Bérat + Tested-by: Frédéric Bérat + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index 9da5ba0c10bf6eee..af03ea4dc6ec0b95 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -152,9 +152,18 @@ copy_and_spawn_sgid (char *child_id, gid_t gid) + p += wrcount; + } + } +- TEST_VERIFY (fchown (outfd, getuid (), gid) == 0); ++ ++ bool chowned = false; ++ TEST_VERIFY ((chowned = fchown (outfd, getuid (), gid) == 0) ++ || errno == EPERM); + if (support_record_failure_is_failed ()) + goto err; ++ else if (!chowned) ++ { ++ ret = 77; ++ goto err; ++ } ++ + TEST_VERIFY (fchmod (outfd, 02750) == 0); + if (support_record_failure_is_failed ()) + goto err; +@@ -191,8 +200,10 @@ err: + free (dirname); + } + ++ if (ret == 77) ++ FAIL_UNSUPPORTED ("Failed to make sgid executable for test\n"); + if (ret != 0) +- FAIL_EXIT1("Failed to make sgid executable for test\n"); ++ FAIL_EXIT1 ("Failed to make sgid executable for test\n"); + + return status; + } diff --git a/SOURCES/glibc-RHEL-92685-3.patch b/SOURCES/glibc-RHEL-92685-3.patch new file mode 100644 index 0000000..39eb3d4 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-3.patch @@ -0,0 +1,86 @@ +commit 5451fa962cd0a90a0e2ec1d8910a559ace02bba0 +Author: Adhemerval Zanella +Date: Mon Nov 6 17:25:49 2023 -0300 + + elf: Ignore LD_LIBRARY_PATH and debug env var for setuid for static + + It mimics the ld.so behavior. + + Checked on x86_64-linux-gnu. + Reviewed-by: Siddhesh Poyarekar + +Conflicts: + elf/dl-support.c + (downstream still uses HAVE_TUNABLES, does not yet + call setup_vdso_pointers, still supports + EXTRA_UNSECURE_ENVVARS) + +diff --git a/elf/dl-support.c b/elf/dl-support.c +index e9943e889ef447ad..008fd90cb43c8803 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -314,33 +314,10 @@ _dl_non_dynamic_init (void) + _dl_main_map.l_phdr = GL(dl_phdr); + _dl_main_map.l_phnum = GL(dl_phnum); + +- _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; +- + /* Set up the data structures for the system-supplied DSO early, + so they can influence _dl_init_paths. */ + setup_vdso (NULL, NULL); + +- /* Initialize the data structures for the search paths for shared +- objects. */ +- _dl_init_paths (getenv ("LD_LIBRARY_PATH"), "LD_LIBRARY_PATH", +- /* No glibc-hwcaps selection support in statically +- linked binaries. */ +- NULL, NULL); +- +- /* Remember the last search directory added at startup. */ +- _dl_init_all_dirs = GL(dl_all_dirs); +- +- _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; +- +- _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; +- +- _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; +- +- _dl_profile_output = getenv ("LD_PROFILE_OUTPUT"); +- if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0') +- _dl_profile_output +- = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0]; +- + if (__libc_enable_secure) + { + static const char unsecure_envvars[] = +@@ -363,6 +340,30 @@ _dl_non_dynamic_init (void) + #endif + } + ++ _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; ++ ++ /* Initialize the data structures for the search paths for shared ++ objects. */ ++ _dl_init_paths (getenv ("LD_LIBRARY_PATH"), "LD_LIBRARY_PATH", ++ /* No glibc-hwcaps selection support in statically ++ linked binaries. */ ++ NULL, NULL); ++ ++ /* Remember the last search directory added at startup. */ ++ _dl_init_all_dirs = GL(dl_all_dirs); ++ ++ _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; ++ ++ _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; ++ ++ _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; ++ ++ _dl_profile_output = getenv ("LD_PROFILE_OUTPUT"); ++ if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0') ++ _dl_profile_output ++ = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0]; ++ ++ + #ifdef DL_PLATFORM_INIT + DL_PLATFORM_INIT; + #endif diff --git a/SOURCES/glibc-RHEL-92685-4.patch b/SOURCES/glibc-RHEL-92685-4.patch new file mode 100644 index 0000000..7ec0cfd --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-4.patch @@ -0,0 +1,41 @@ +commit d0b8aa6de4529231fadfe604ac2c434e559c2d9e +Author: Florian Weimer +Date: Mon Dec 23 13:57:55 2024 +0100 + + support: Add support_record_failure_barrier + + This can be used to stop execution after a TEST_COMPARE_BLOB + failure, for example. + +diff --git a/support/check.h b/support/check.h +index 7ea9a86a9c7ed055..d435479963945bb9 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -187,6 +187,9 @@ void support_record_failure_reset (void); + failures or not. */ + int support_record_failure_is_failed (void); + ++/* Terminate the process if any failures have been encountered so far. */ ++void support_record_failure_barrier (void); ++ + __END_DECLS + + #endif /* SUPPORT_CHECK_H */ +diff --git a/support/support_record_failure.c b/support/support_record_failure.c +index 17ab1d80ef2bbdea..8d0f3852dcf60a70 100644 +--- a/support/support_record_failure.c ++++ b/support/support_record_failure.c +@@ -112,3 +112,13 @@ support_record_failure_is_failed (void) + synchronization for reliable test error reporting anyway. */ + return __atomic_load_n (&state->failed, __ATOMIC_RELAXED); + } ++ ++void ++support_record_failure_barrier (void) ++{ ++ if (__atomic_load_n (&state->failed, __ATOMIC_RELAXED)) ++ { ++ puts ("error: exiting due to previous errors"); ++ exit (1); ++ } ++} diff --git a/SOURCES/glibc-RHEL-92685-5.patch b/SOURCES/glibc-RHEL-92685-5.patch new file mode 100644 index 0000000..21d5ba7 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-5.patch @@ -0,0 +1,56 @@ +commit f0c09fe61678df6f7f18fe1ebff074e62fa5ca7a +Author: Florian Weimer +Date: Tue May 20 19:36:02 2025 +0200 + + support: Use const char * argument in support_capture_subprogram_self_sgid + + The function does not modify the passed-in string, so make this clear + via the prototype. + + Reviewed-by: Carlos O'Donell + +diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h +index 72fb30504684a84e..67c0cd82597805bd 100644 +--- a/support/capture_subprocess.h ++++ b/support/capture_subprocess.h +@@ -44,8 +44,7 @@ struct support_capture_subprocess support_capture_subprogram + /* Copy the running program into a setgid binary and run it with CHILD_ID + argument. If execution is successful, return the exit status of the child + program, otherwise return a non-zero failure exit code. */ +-int support_capture_subprogram_self_sgid +- (char *child_id); ++int support_capture_subprogram_self_sgid (const char *child_id); + + /* Deallocate the subprocess data captured by + support_capture_subprocess. */ +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index af03ea4dc6ec0b95..48c2ab839dca33ea 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -108,7 +108,7 @@ support_capture_subprogram (const char *file, char *const argv[]) + safely make it SGID with the TARGET group ID. Then runs the + executable. */ + static int +-copy_and_spawn_sgid (char *child_id, gid_t gid) ++copy_and_spawn_sgid (const char *child_id, gid_t gid) + { + char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd", + test_dir, (intmax_t) getpid ()); +@@ -180,7 +180,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid) + ret = 0; + infd = outfd = -1; + +- char * const args[] = {execname, child_id, NULL}; ++ char * const args[] = {execname, (char *) child_id, NULL}; + + status = support_subprogram_wait (args[0], args); + +@@ -209,7 +209,7 @@ err: + } + + int +-support_capture_subprogram_self_sgid (char *child_id) ++support_capture_subprogram_self_sgid (const char *child_id) + { + gid_t target = 0; + const int count = 64; diff --git a/SOURCES/glibc-RHEL-92685-6.patch b/SOURCES/glibc-RHEL-92685-6.patch new file mode 100644 index 0000000..012dfc2 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-6.patch @@ -0,0 +1,159 @@ +commit d8f7a79335b0d861c12c42aec94c04cd5bb181e2 +Author: Florian Weimer +Date: Tue May 20 19:36:02 2025 +0200 + + elf: Test case for bug 32976 (CVE-2025-4802) + + Check that LD_LIBRARY_PATH is ignored for AT_SECURE statically + linked binaries, using support_capture_subprogram_self_sgid. + + Reviewed-by: Carlos O'Donell + +Conflicts: + elf/Makefile + ((test list differences, link against libdl)) + +diff --git a/elf/Makefile b/elf/Makefile +index 8ca9f1c13f78216d..38976f195a398abf 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -235,6 +235,7 @@ tests-static-normal := \ + tst-array1-static \ + tst-array5-static \ + tst-dl-iter-static \ ++ tst-dlopen-sgid \ + tst-dst-static \ + tst-env-setuid \ + tst-env-setuid-tunables \ +@@ -726,6 +727,7 @@ modules-names = \ + tst-dlmopen-gethostbyname-mod \ + tst-dlmopen-twice-mod1 \ + tst-dlmopen-twice-mod2 \ ++ tst-dlopen-sgid-mod \ + tst-dlopen-tlsreinitmod1 \ + tst-dlopen-tlsreinitmod2 \ + tst-dlopen-tlsreinitmod3 \ +@@ -2816,3 +2818,6 @@ $(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so + tst-dlopen-tlsreinit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + $(objpfx)tst-dlopen-tlsreinit4.out: $(objpfx)tst-auditmod1.so + tst-dlopen-tlsreinit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so ++ ++$(objpfx)tst-dlopen-sgid: $(common-objpfx)dlfcn/libdl.a ++$(objpfx)tst-dlopen-sgid.out: $(objpfx)tst-dlopen-sgid-mod.so +diff --git a/elf/tst-dlopen-sgid-mod.c b/elf/tst-dlopen-sgid-mod.c +new file mode 100644 +index 0000000000000000..5eb79eef485da4c9 +--- /dev/null ++++ b/elf/tst-dlopen-sgid-mod.c +@@ -0,0 +1 @@ ++/* Opening this object should not succeed. */ +diff --git a/elf/tst-dlopen-sgid.c b/elf/tst-dlopen-sgid.c +new file mode 100644 +index 0000000000000000..47829a405e90b6b9 +--- /dev/null ++++ b/elf/tst-dlopen-sgid.c +@@ -0,0 +1,104 @@ ++/* Test case for ignored LD_LIBRARY_PATH in static startug (bug 32976). ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* This is the name of our test object. Use a custom module for ++ testing, so that this object does not get picked up from the system ++ path. */ ++static const char dso_name[] = "tst-dlopen-sgid-mod.so"; ++ ++/* Used to mark the recursive invocation. */ ++static const char magic_argument[] = "run-actual-test"; ++ ++static int ++do_test (void) ++{ ++/* Pathname of the directory that receives the shared objects this ++ test attempts to load. */ ++ char *libdir = support_create_temp_directory ("tst-dlopen-sgid-"); ++ ++ /* This is supposed to be ignored and stripped. */ ++ TEST_COMPARE (setenv ("LD_LIBRARY_PATH", libdir, 1), 0); ++ ++ /* Copy of libc.so.6. */ ++ { ++ char *from = xasprintf ("%s/%s", support_objdir_root, LIBC_SO); ++ char *to = xasprintf ("%s/%s", libdir, LIBC_SO); ++ add_temp_file (to); ++ support_copy_file (from, to); ++ free (to); ++ free (from); ++ } ++ ++ /* Copy of the test object. */ ++ { ++ char *from = xasprintf ("%s/elf/%s", support_objdir_root, dso_name); ++ char *to = xasprintf ("%s/%s", libdir, dso_name); ++ add_temp_file (to); ++ support_copy_file (from, to); ++ free (to); ++ free (from); ++ } ++ ++ TEST_COMPARE (support_capture_subprogram_self_sgid (magic_argument), 0); ++ ++ free (libdir); ++ ++ return 0; ++} ++ ++static void ++alternative_main (int argc, char **argv) ++{ ++ if (argc == 2 && strcmp (argv[1], magic_argument) == 0) ++ { ++ if (getgid () == getegid ()) ++ /* This can happen if the file system is mounted nosuid. */ ++ FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n", ++ (intmax_t) getgid ()); ++ ++ /* Should be removed due to SGID. */ ++ TEST_COMPARE_STRING (getenv ("LD_LIBRARY_PATH"), NULL); ++ ++ TEST_VERIFY (dlopen (dso_name, RTLD_NOW) == NULL); ++ { ++ const char *message = dlerror (); ++ TEST_COMPARE_STRING (message, ++ "tst-dlopen-sgid-mod.so:" ++ " cannot open shared object file:" ++ " No such file or directory"); ++ } ++ ++ support_record_failure_barrier (); ++ exit (EXIT_SUCCESS); ++ } ++} ++ ++#define PREPARE alternative_main ++#include diff --git a/SOURCES/glibc-RHEL-92685-7.patch b/SOURCES/glibc-RHEL-92685-7.patch new file mode 100644 index 0000000..78a1a20 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-7.patch @@ -0,0 +1,42 @@ +commit 35fc356fa3b4f485bd3ba3114c9f774e5df7d3c2 +Author: Florian Weimer +Date: Wed May 21 08:43:32 2025 +0200 + + elf: Fix subprocess status handling for tst-dlopen-sgid (bug 32987) + + This should really move into support_capture_subprogram_self_sgid. + + Reviewed-by: Sam James + +diff --git a/elf/tst-dlopen-sgid.c b/elf/tst-dlopen-sgid.c +index 47829a405e90b6b9..5688b79f2e870b1d 100644 +--- a/elf/tst-dlopen-sgid.c ++++ b/elf/tst-dlopen-sgid.c +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + #include + + /* This is the name of our test object. Use a custom module for +@@ -66,10 +68,16 @@ do_test (void) + free (from); + } + +- TEST_COMPARE (support_capture_subprogram_self_sgid (magic_argument), 0); +- + free (libdir); + ++ int status = support_capture_subprogram_self_sgid (magic_argument); ++ ++ if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) ++ return EXIT_UNSUPPORTED; ++ ++ if (!WIFEXITED (status)) ++ FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status); ++ + return 0; + } + diff --git a/SOURCES/glibc-RHEL-92685-8.patch b/SOURCES/glibc-RHEL-92685-8.patch new file mode 100644 index 0000000..a0987b6 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-8.patch @@ -0,0 +1,105 @@ +commit 2f769cec448d84a62b7dd0d4ff56978fe22c0cd6 +Author: Florian Weimer +Date: Wed May 21 16:47:34 2025 +0200 + + support: Pick group in support_capture_subprogram_self_sgid if UID == 0 + + When running as root, it is likely that we can run under any group. + Pick a harmless group from /etc/group in this case. + + Reviewed-by: Carlos O'Donell + +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index 48c2ab839dca33ea..774deacd5fe2b6cc 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -21,7 +21,11 @@ + + #include + #include ++#include ++#include ++#include + #include ++#include + #include + #include + #include +@@ -208,10 +212,48 @@ err: + return status; + } + ++/* Returns true if a group with NAME has been found, and writes its ++ GID to *TARGET. */ ++static bool ++find_sgid_group (gid_t *target, const char *name) ++{ ++ /* Do not use getgrname_r because it does not work in statically ++ linked binaries if the system libc is different. */ ++ FILE *fp = fopen ("/etc/group", "rce"); ++ if (fp == NULL) ++ return false; ++ __fsetlocking (fp, FSETLOCKING_BYCALLER); ++ ++ bool ok = false; ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ while (true) ++ { ++ struct group grp; ++ struct group *result = NULL; ++ int status = fgetgrent_r (fp, &grp, buf.data, buf.length, &result); ++ if (status == 0 && result != NULL) ++ { ++ if (strcmp (result->gr_name, name) == 0) ++ { ++ *target = result->gr_gid; ++ ok = true; ++ break; ++ } ++ } ++ else if (errno != ERANGE) ++ break; ++ else if (!scratch_buffer_grow (&buf)) ++ break; ++ } ++ scratch_buffer_free (&buf); ++ fclose (fp); ++ return ok; ++} ++ + int + support_capture_subprogram_self_sgid (const char *child_id) + { +- gid_t target = 0; + const int count = 64; + gid_t groups[count]; + +@@ -223,6 +265,7 @@ support_capture_subprogram_self_sgid (const char *child_id) + (intmax_t) getuid ()); + + gid_t current = getgid (); ++ gid_t target = current; + for (int i = 0; i < ret; ++i) + { + if (groups[i] != current) +@@ -232,9 +275,16 @@ support_capture_subprogram_self_sgid (const char *child_id) + } + } + +- if (target == 0) +- FAIL_UNSUPPORTED("Could not find a suitable GID for user %jd\n", +- (intmax_t) getuid ()); ++ if (target == current) ++ { ++ /* If running as root, try to find a harmless group for SGID. */ ++ if (getuid () != 0 ++ || (!find_sgid_group (&target, "nogroup") ++ && !find_sgid_group (&target, "bin") ++ && !find_sgid_group (&target, "daemon"))) ++ FAIL_UNSUPPORTED("Could not find a suitable GID for user %jd\n", ++ (intmax_t) getuid ()); ++ } + + return copy_and_spawn_sgid (child_id, target); + } diff --git a/SOURCES/glibc-RHEL-92685-9.patch b/SOURCES/glibc-RHEL-92685-9.patch new file mode 100644 index 0000000..d7804e7 --- /dev/null +++ b/SOURCES/glibc-RHEL-92685-9.patch @@ -0,0 +1,315 @@ +commit 3a3fb2ed83f79100c116c824454095ecfb335ad7 +Author: Florian Weimer +Date: Thu May 22 14:36:37 2025 +0200 + + Fix error reporting (false negatives) in SGID tests + + And simplify the interface of support_capture_subprogram_self_sgid. + + Use the existing framework for temporary directories (now with + mode 0700) and directory/file deletion. Handle all execution + errors within support_capture_subprogram_self_sgid. In particular, + this includes test failures because the invoked program did not + exit with exit status zero. Existing tests that expect exit + status 42 are adjusted to use zero instead. + + In addition, fix callers not to call exit (0) with test failures + pending (which may mask them, especially when running with --direct). + + Fixes commit 35fc356fa3b4f485bd3ba3114c9f774e5df7d3c2 + ("elf: Fix subprocess status handling for tst-dlopen-sgid (bug 32987)"). + + Reviewed-by: Carlos O'Donell + +Conflicts: + elf/tst-env-setuid.c + (missing commit 11f7e3dd8fed66e0b8740af440cd3151e55a466f + ("elf: Add all malloc tunable to unsecvars") downstream) + +diff --git a/elf/tst-dlopen-sgid.c b/elf/tst-dlopen-sgid.c +index 5688b79f2e870b1d..8aec52e19fc56aba 100644 +--- a/elf/tst-dlopen-sgid.c ++++ b/elf/tst-dlopen-sgid.c +@@ -70,13 +70,7 @@ do_test (void) + + free (libdir); + +- int status = support_capture_subprogram_self_sgid (magic_argument); +- +- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) +- return EXIT_UNSUPPORTED; +- +- if (!WIFEXITED (status)) +- FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status); ++ support_capture_subprogram_self_sgid (magic_argument); + + return 0; + } +diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c +index 8b0861c4ad853040..dfbea3118fa9daf8 100644 +--- a/elf/tst-env-setuid-tunables.c ++++ b/elf/tst-env-setuid-tunables.c +@@ -127,10 +127,7 @@ do_test (int argc, char **argv) + + if (ret != 0) + exit (1); +- +- /* Special return code to make sure that the child executed all the way +- through. */ +- exit (42); ++ return 0; + } + else + { +@@ -149,18 +146,7 @@ do_test (int argc, char **argv) + continue; + } + +- int status = support_capture_subprogram_self_sgid (buf); +- +- /* Bail out early if unsupported. */ +- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) +- return EXIT_UNSUPPORTED; +- +- if (WEXITSTATUS (status) != 42) +- { +- printf (" [%d] child failed with status %d\n", i, +- WEXITSTATUS (status)); +- support_record_failure (); +- } ++ support_capture_subprogram_self_sgid (buf); + } + return 0; + } +diff --git a/elf/tst-env-setuid.c b/elf/tst-env-setuid.c +index eda87f9dda293e79..04f6b0025fc86cfa 100644 +--- a/elf/tst-env-setuid.c ++++ b/elf/tst-env-setuid.c +@@ -103,21 +103,14 @@ do_test (int argc, char **argv) + + if (ret != 0) + exit (1); +- +- exit (EXIT_SUCCESS); ++ return 0; + } + else + { + if (test_parent () != 0) + exit (1); + +- int status = support_capture_subprogram_self_sgid (SETGID_CHILD); +- +- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) +- return EXIT_UNSUPPORTED; +- +- if (!WIFEXITED (status)) +- FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status); ++ support_capture_subprogram_self_sgid (SETGID_CHILD); + + return 0; + } +diff --git a/stdlib/tst-secure-getenv.c b/stdlib/tst-secure-getenv.c +index 156c92fea216729f..bda73a203498a90f 100644 +--- a/stdlib/tst-secure-getenv.c ++++ b/stdlib/tst-secure-getenv.c +@@ -57,13 +57,7 @@ do_test (void) + exit (1); + } + +- int status = support_capture_subprogram_self_sgid (MAGIC_ARGUMENT); +- +- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) +- return EXIT_UNSUPPORTED; +- +- if (!WIFEXITED (status)) +- FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status); ++ support_capture_subprogram_self_sgid (MAGIC_ARGUMENT); + + return 0; + } +@@ -82,6 +76,7 @@ alternative_main (int argc, char **argv) + if (secure_getenv ("PATH") != NULL) + FAIL_EXIT (4, "PATH variable not filtered out\n"); + ++ support_record_failure_barrier (); + exit (EXIT_SUCCESS); + } + } +diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h +index 67c0cd82597805bd..a7eef351ce1b276c 100644 +--- a/support/capture_subprocess.h ++++ b/support/capture_subprocess.h +@@ -41,10 +41,12 @@ struct support_capture_subprocess support_capture_subprocess + struct support_capture_subprocess support_capture_subprogram + (const char *file, char *const argv[]); + +-/* Copy the running program into a setgid binary and run it with CHILD_ID +- argument. If execution is successful, return the exit status of the child +- program, otherwise return a non-zero failure exit code. */ +-int support_capture_subprogram_self_sgid (const char *child_id); ++/* Copy the running program into a setgid binary and run it with ++ CHILD_ID argument. If the program exits with a non-zero status, ++ exit with that exit status (or status 1 if the program did not exit ++ normally). If the test cannot be performed, exit with ++ EXIT_UNSUPPORTED. */ ++void support_capture_subprogram_self_sgid (const char *child_id); + + /* Deallocate the subprocess data captured by + support_capture_subprocess. */ +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index 774deacd5fe2b6cc..25f79b760a9e414d 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + + static void +@@ -111,105 +112,44 @@ support_capture_subprogram (const char *file, char *const argv[]) + /* Copies the executable into a restricted directory, so that we can + safely make it SGID with the TARGET group ID. Then runs the + executable. */ +-static int ++static void + copy_and_spawn_sgid (const char *child_id, gid_t gid) + { +- char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd", +- test_dir, (intmax_t) getpid ()); ++ char *dirname = support_create_temp_directory ("tst-glibc-sgid-"); + char *execname = xasprintf ("%s/bin", dirname); +- int infd = -1; +- int outfd = -1; +- int ret = 1, status = 1; +- +- TEST_VERIFY (mkdir (dirname, 0700) == 0); +- if (support_record_failure_is_failed ()) +- goto err; ++ add_temp_file (execname); + +- infd = open ("/proc/self/exe", O_RDONLY); +- if (infd < 0) ++ if (access ("/proc/self/exe", R_OK) != 0) + FAIL_UNSUPPORTED ("unsupported: Cannot read binary from procfs\n"); + +- outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700); +- TEST_VERIFY (outfd >= 0); +- if (support_record_failure_is_failed ()) +- goto err; +- +- char buf[4096]; +- for (;;) +- { +- ssize_t rdcount = read (infd, buf, sizeof (buf)); +- TEST_VERIFY (rdcount >= 0); +- if (support_record_failure_is_failed ()) +- goto err; +- if (rdcount == 0) +- break; +- char *p = buf; +- char *end = buf + rdcount; +- while (p != end) +- { +- ssize_t wrcount = write (outfd, buf, end - p); +- if (wrcount == 0) +- errno = ENOSPC; +- TEST_VERIFY (wrcount > 0); +- if (support_record_failure_is_failed ()) +- goto err; +- p += wrcount; +- } +- } ++ support_copy_file ("/proc/self/exe", execname); + +- bool chowned = false; +- TEST_VERIFY ((chowned = fchown (outfd, getuid (), gid) == 0) +- || errno == EPERM); +- if (support_record_failure_is_failed ()) +- goto err; +- else if (!chowned) +- { +- ret = 77; +- goto err; +- } ++ if (chown (execname, getuid (), gid) != 0) ++ FAIL_UNSUPPORTED ("cannot change group of \"%s\" to %jd: %m", ++ execname, (intmax_t) gid); + +- TEST_VERIFY (fchmod (outfd, 02750) == 0); +- if (support_record_failure_is_failed ()) +- goto err; +- TEST_VERIFY (close (outfd) == 0); +- if (support_record_failure_is_failed ()) +- goto err; +- TEST_VERIFY (close (infd) == 0); +- if (support_record_failure_is_failed ()) +- goto err; ++ if (chmod (execname, 02750) != 0) ++ FAIL_UNSUPPORTED ("cannot make \"%s\" SGID: %m ", execname); + + /* We have the binary, now spawn the subprocess. Avoid using + support_subprogram because we only want the program exit status, not the + contents. */ +- ret = 0; +- infd = outfd = -1; + + char * const args[] = {execname, (char *) child_id, NULL}; ++ int status = support_subprogram_wait (args[0], args); + +- status = support_subprogram_wait (args[0], args); ++ free (execname); ++ free (dirname); + +-err: +- if (outfd >= 0) +- close (outfd); +- if (infd >= 0) +- close (infd); +- if (execname != NULL) +- { +- unlink (execname); +- free (execname); +- } +- if (dirname != NULL) ++ if (WIFEXITED (status)) + { +- rmdir (dirname); +- free (dirname); ++ if (WEXITSTATUS (status) == 0) ++ return; ++ else ++ exit (WEXITSTATUS (status)); + } +- +- if (ret == 77) +- FAIL_UNSUPPORTED ("Failed to make sgid executable for test\n"); +- if (ret != 0) +- FAIL_EXIT1 ("Failed to make sgid executable for test\n"); +- +- return status; ++ else ++ FAIL_EXIT1 ("subprogram failed with status %d", status); + } + + /* Returns true if a group with NAME has been found, and writes its +@@ -251,7 +191,7 @@ find_sgid_group (gid_t *target, const char *name) + return ok; + } + +-int ++void + support_capture_subprogram_self_sgid (const char *child_id) + { + const int count = 64; +@@ -286,7 +226,7 @@ support_capture_subprogram_self_sgid (const char *child_id) + (intmax_t) getuid ()); + } + +- return copy_and_spawn_sgid (child_id, target); ++ copy_and_spawn_sgid (child_id, target); + } + + void diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index 30ed19a..d0e221e 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -115,7 +115,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: %{glibcrelease}.16 +Release: %{glibcrelease}.22 # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1262,6 +1262,21 @@ Patch1027: glibc-RHEL-78390.patch Patch1028: glibc-RHEL-83306-1.patch Patch1029: glibc-RHEL-83306-2.patch Patch1030: glibc-RHEL-35280.patch +Patch1031: glibc-RHEL-76211.patch +Patch1032: glibc-RHEL-76387.patch +Patch1033: glibc-RHEL-86018-1.patch +Patch1034: glibc-RHEL-86018-2.patch +Patch1035: glibc-RHEL-88813.patch +Patch1036: glibc-RHEL-71921.patch +Patch1037: glibc-RHEL-92685-1.patch +Patch1038: glibc-RHEL-92685-2.patch +Patch1039: glibc-RHEL-92685-3.patch +Patch1040: glibc-RHEL-92685-4.patch +Patch1041: glibc-RHEL-92685-5.patch +Patch1042: glibc-RHEL-92685-6.patch +Patch1043: glibc-RHEL-92685-7.patch +Patch1044: glibc-RHEL-92685-8.patch +Patch1045: glibc-RHEL-92685-9.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2923,6 +2938,25 @@ fi %{_libdir}/libpthread_nonshared.a %changelog +* Mon May 26 2025 Florian Weimer - 2.28-251.22 +- CVE-2025-4802: static setuid dlopen may search LD_LIBRARY_PATH (RHEL-92685) + +* Wed May 14 2025 Patsy Griffin - 2.28-251.21 +- elf: Keep using minimal malloc after early DTV resize (RHEL-71921) + +* Fri May 02 2025 Patsy Griffin - 2.28-251.20 +- Add missing libnss_testX.so requirement for tst-nss-test3 (RHEL-88813) + +* Fri Apr 25 2025 Patsy Griffin - 2.28-251.19 +- libio: Fix a deadlock after fork in popen +- libio: Correctly link tst-popen-fork against libpthread (RHEL-86018) + +* Fri Apr 18 2025 Patsy Griffin - 2.28-251.18 +- x86: Avoid integer truncation with large cache sizes (RHEL-76387) + +* Wed Apr 16 2025 Patsy Griffin - 2.28-251.17 +- x86: Check the lower byte of EAX of CPUID leaf 2 (RHEL-76211) + * Thu Mar 27 2025 Arjun Shankar - 2.28-251.16 - nscd: Fix an unlikely TTL issue in the netgroup cache (RHEL-35280)