import UBI glibc-2.28-251.el8_10.22

This commit is contained in:
eabdullin 2025-06-09 19:16:28 +00:00
parent ff081255d2
commit 73b8a454b8
16 changed files with 1457 additions and 1 deletions

View File

@ -0,0 +1,188 @@
commit aa3d7bd5299b33bffc118aa618b59bfa66059bcb
Author: Florian Weimer <fweimer@redhat.com>
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 <dj@redhat.com>
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
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/xdlfcn.h>
+#include <stdio.h>
+
+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 <support/test-driver.c>
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
+ <https://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <link.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+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;
+}

View File

@ -0,0 +1,69 @@
commit 1493622f4f9048ffede3fbedb64695efa49d662a
Author: H.J. Lu <hjl.tools@gmail.com>
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,

View File

@ -0,0 +1,32 @@
commit 61c3450db96dce96ad2b24b4f0b548e6a46d68e5
Author: Florian Weimer <fweimer@redhat.com>
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))
{

View File

@ -0,0 +1,194 @@
commit 9f0d2c0ee6c728643fcf9a4879e9f20f5e45ce5f
Author: Arjun Shankar <arjun@redhat.com>
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 <fweimer@redhat.com>
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
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdatomic.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <support/check.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+
+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 <support/test-driver.c>
--- 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. */

View File

@ -0,0 +1,29 @@
commit 6a290b2895b77be839fcb7c44a6a9879560097ad
Author: Arjun Shankar <arjun@redhat.com>
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 <fweimer@redhat.com>
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))

View File

@ -0,0 +1,31 @@
commit 268bb71e475d7e40fad83313be0eeb173e599c92
Author: Stefan Liebler <stli@linux.ibm.com>
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) \

View File

@ -0,0 +1,23 @@
commit 45caed9d67a00af917d8b5b88d4b5eb1225b7aef
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
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 <arjun@redhat.com>
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};

View File

@ -0,0 +1,52 @@
commit 6286cca2cb8389dcffec39238a8bf15ffea96396
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
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 <fberat@redhat.com>
Tested-by: Frédéric Bérat <fberat@redhat.com>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
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;
}

View File

@ -0,0 +1,86 @@
commit 5451fa962cd0a90a0e2ec1d8910a559ace02bba0
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
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 <siddhesh@sourceware.org>
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

View File

@ -0,0 +1,41 @@
commit d0b8aa6de4529231fadfe604ac2c434e559c2d9e
Author: Florian Weimer <fweimer@redhat.com>
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);
+ }
+}

View File

@ -0,0 +1,56 @@
commit f0c09fe61678df6f7f18fe1ebff074e62fa5ca7a
Author: Florian Weimer <fweimer@redhat.com>
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 <carlos@redhat.com>
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;

View File

@ -0,0 +1,159 @@
commit d8f7a79335b0d861c12c42aec94c04cd5bb181e2
Author: Florian Weimer <fweimer@redhat.com>
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 <carlos@redhat.com>
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
+ <https://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <gnu/lib-names.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <unistd.h>
+
+/* 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 <support/test-driver.c>

View File

@ -0,0 +1,42 @@
commit 35fc356fa3b4f485bd3ba3114c9f774e5df7d3c2
Author: Florian Weimer <fweimer@redhat.com>
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 <sam@gentoo.org>
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 <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <sys/wait.h>
#include <unistd.h>
/* 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;
}

View File

@ -0,0 +1,105 @@
commit 2f769cec448d84a62b7dd0d4ff56978fe22c0cd6
Author: Florian Weimer <fweimer@redhat.com>
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 <carlos@redhat.com>
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 <errno.h>
#include <fcntl.h>
+#include <grp.h>
+#include <scratch_buffer.h>
+#include <stdio_ext.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/xunistd.h>
#include <support/xsocket.h>
@@ -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);
}

View File

@ -0,0 +1,315 @@
commit 3a3fb2ed83f79100c116c824454095ecfb335ad7
Author: Florian Weimer <fweimer@redhat.com>
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 <carlos@redhat.com>
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 <support/xsocket.h>
#include <support/xspawn.h>
#include <support/support.h>
+#include <support/temp_file.h>
#include <support/test-driver.h>
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

View File

@ -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 <fweimer@redhat.com> - 2.28-251.22
- CVE-2025-4802: static setuid dlopen may search LD_LIBRARY_PATH (RHEL-92685)
* Wed May 14 2025 Patsy Griffin <patsy@redhat.com> - 2.28-251.21
- elf: Keep using minimal malloc after early DTV resize (RHEL-71921)
* Fri May 02 2025 Patsy Griffin <patsy@redhat.com> - 2.28-251.20
- Add missing libnss_testX.so requirement for tst-nss-test3 (RHEL-88813)
* Fri Apr 25 2025 Patsy Griffin <patsy@redhat.com> - 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 <patsy@redhat.com> - 2.28-251.18
- x86: Avoid integer truncation with large cache sizes (RHEL-76387)
* Wed Apr 16 2025 Patsy Griffin <patsy@redhat.com> - 2.28-251.17
- x86: Check the lower byte of EAX of CPUID leaf 2 (RHEL-76211)
* Thu Mar 27 2025 Arjun Shankar <arjun@redhat.com> - 2.28-251.16
- nscd: Fix an unlikely TTL issue in the netgroup cache (RHEL-35280)