From b98ca5a4c8e868393599993fd246fd3612e0d459 Mon Sep 17 00:00:00 2001 From: Patsy Griffin Date: Wed, 14 May 2025 11:22:27 -0400 Subject: [PATCH] elf: Keep using minimal malloc after early DTV resize (RHEL-71921) Resolves: RHEL-71921 --- glibc-RHEL-71921.patch | 188 +++++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-71921.patch diff --git a/glibc-RHEL-71921.patch b/glibc-RHEL-71921.patch new file mode 100644 index 0000000..605e645 --- /dev/null +++ b/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/glibc.spec b/glibc.spec index 67651d7..98f7a16 100644 --- a/glibc.spec +++ b/glibc.spec @@ -115,7 +115,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: %{glibcrelease}.20 +Release: %{glibcrelease}.21 # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1267,6 +1267,7 @@ 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 ############################################################################## # Continued list of core "glibc" package information: @@ -2928,6 +2929,9 @@ fi %{_libdir}/libpthread_nonshared.a %changelog +* 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)