From 9f58ea3da06ac16a6e32654016a260367a900516 Mon Sep 17 00:00:00 2001 From: shixuantong Date: Fri, 6 Dec 2024 11:00:19 +0800 Subject: [PATCH] sync some patch for elf details: - elf: Handle static PIE with non-zero load address - elf: Introduce _dl_relocate_object_no_relro - elf: Switch to main malloc after final ld.so self-relocation (cherry picked from commit d5144c30f4202cb51dd5b71db984b595cbae5ca3) --- 0001-fix-glibc-build-error-on-x86.patch | 14 +- ...c-PIE-with-non-zero-load-address-BZ-.patch | 306 ++++++++++++++++++ ...troduce-_dl_relocate_object_no_relro.patch | 89 +++++ ...in-malloc-after-final-ld.so-self-rel.patch | 217 +++++++++++++ glibc.spec | 10 +- 5 files changed, 629 insertions(+), 7 deletions(-) create mode 100644 backport-elf-Handle-static-PIE-with-non-zero-load-address-BZ-.patch create mode 100644 backport-elf-Introduce-_dl_relocate_object_no_relro.patch create mode 100644 backport-elf-Switch-to-main-malloc-after-final-ld.so-self-rel.patch diff --git a/0001-fix-glibc-build-error-on-x86.patch b/0001-fix-glibc-build-error-on-x86.patch index c27dd9d..f0a8dea 100644 --- a/0001-fix-glibc-build-error-on-x86.patch +++ b/0001-fix-glibc-build-error-on-x86.patch @@ -4,7 +4,7 @@ Date: Wed, 16 Aug 2023 15:47:44 +0800 Subject: [PATCH] skipping test case building fix glibc build error on x86 Due to the upgrade of binutils to version 2.40, -support for the -z pack-relative-relocs +support for the -z pack-relative-relocs compilation option was added during glibc building. This caused the linking failure of the test cases tst-protected1a, tst-protected1b, and vismain. @@ -17,10 +17,10 @@ To ensure the successful building of glibc, these files are temporarily skipped. 1 file changed, 19 deletions(-) diff --git a/elf/Makefile b/elf/Makefile -index c00e2ccf..8cd01845 100644 +index 82e7ef18..cebc4a2a 100644 --- a/elf/Makefile +++ b/elf/Makefile -@@ -986,30 +986,11 @@ tst-gnu2-tls1mod.so-no-z-defs = yes +@@ -993,20 +993,6 @@ tst-gnu2-tls1mod.so-no-z-defs = yes CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 endif # $(have-mtls-dialect-gnu2) @@ -41,8 +41,10 @@ index c00e2ccf..8cd01845 100644 ifeq (yesyes,$(have-fpie)$(build-shared)) modules-names += tst-piemod1 tests += tst-pie1 tst-pie2 tst-dlopen-pie tst-dlopen-tlsmodid-pie \ - tst-dlopen-self-pie - tests-pie += tst-pie1 tst-pie2 tst-dlopen-tlsmodid-pie tst-dlopen-self-pie +@@ -1031,11 +1017,6 @@ LDFLAGS-tst-pie-address-static += \ + $(load-address-ldflag)=$(pde-load-address) + endif + endif -ifeq (yes,$(have-protected-data)) -tests += vismain -tests-pie += vismain @@ -52,5 +54,5 @@ index c00e2ccf..8cd01845 100644 modules-execstack-yes = tst-execstack-mod extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) -- -2.41.0 +2.27.0 diff --git a/backport-elf-Handle-static-PIE-with-non-zero-load-address-BZ-.patch b/backport-elf-Handle-static-PIE-with-non-zero-load-address-BZ-.patch new file mode 100644 index 0000000..e926107 --- /dev/null +++ b/backport-elf-Handle-static-PIE-with-non-zero-load-address-BZ-.patch @@ -0,0 +1,306 @@ +From e7b553272196e6175b8a15f807cb59217ba2843a Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 29 Oct 2024 06:01:14 +0800 +Subject: [PATCH] elf: Handle static PIE with non-zero load address [BZ #31799] + +For a static PIE with non-zero load address, its PT_DYNAMIC segment +entries contain the relocated values for the load address in static PIE. +Since static PIE usually doesn't have PT_PHDR segment, use p_vaddr of +the PT_LOAD segment with offset == 0 as the load address in static PIE +and adjust the entries of PT_DYNAMIC segment in static PIE by properly +setting the l_addr field for static PIE. This fixes BZ #31799. + +Signed-off-by: H.J. Lu +Reviewed-by: Noah Goldstein +--- + configure | 74 ++++++++++++++++++++++++++++++++++++ + configure.ac | 36 ++++++++++++++++++ + elf/Makefile | 20 ++++++++++ + elf/dl-reloc-static-pie.c | 30 +++++++++++---- + elf/tst-pie-address-static.c | 19 +++++++++ + elf/tst-pie-address.c | 28 ++++++++++++++ + 6 files changed, 200 insertions(+), 7 deletions(-) + create mode 100644 elf/tst-pie-address-static.c + create mode 100644 elf/tst-pie-address.c + +diff --git a/configure b/configure +index 4ef38714..75f1a5fd 100755 +--- a/configure ++++ b/configure +@@ -7925,6 +7925,80 @@ printf "%s\n" "$libc_cv_cc_pie_default" >&6; } + config_vars="$config_vars + cc-pie-default = $libc_cv_cc_pie_default" + ++# Get Position Dependent Executable (PDE) load address to be used to ++# load static Position Independent Executable (PIE) at a known working ++# non-zero load address. This is only used by glibc tests to verify ++# that PIE and static PIE with non-zero load address work correctly. ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PDE load address" >&5 ++printf %s "checking PDE load address... " >&6; } ++if test ${libc_cv_pde_load_address+y} ++then : ++ printf %s "(cached) " >&6 ++else case e in #( ++ e) cat > conftest.S <&5 2>&5; then ++ # Get the load address of the first PT_LOAD segment. ++ libc_cv_pde_load_address=$(LC_ALL=C $READELF -Wl conftest \ ++ | $AWK '/LOAD/ { print $3; exit 0; }') ++else ++ as_fn_error $? "${CC-cc} can not create PDE" "$LINENO" 5 ++fi ++rm -f conftest* ;; ++esac ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pde_load_address" >&5 ++printf "%s\n" "$libc_cv_pde_load_address" >&6; } ++config_vars="$config_vars ++pde-load-address = $libc_cv_pde_load_address" ++ ++# Get the linker command-line option to load executable at a non-zero ++# load address. This is only used by glibc tests to verify that PIE and ++# static PIE with non-zero load address work correctly. ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -Ttext-segment=$libc_cv_pde_load_address" >&5 ++printf %s "checking for linker that supports -Ttext-segment=$libc_cv_pde_load_address... " >&6; } ++libc_linker_feature=no ++cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ++then ++ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-Ttext-segment=$libc_cv_pde_load_address -nostdlib \ ++ -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \ ++ | grep "warning: -Ttext-segment=$libc_cv_pde_load_address ignored" > /dev/null 2>&1; then ++ true ++ else ++ libc_linker_feature=yes ++ fi ++fi ++rm -f conftest* ++if test $libc_linker_feature = yes; then ++ libc_cv_load_address_ldflag=-Wl,-Ttext-segment ++else ++ libc_cv_load_address_ldflag= ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5 ++printf "%s\n" "$libc_linker_feature" >&6; } ++config_vars="$config_vars ++load-address-ldflag = $libc_cv_load_address_ldflag" ++ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can build programs as PIE" >&5 + printf %s "checking if we can build programs as PIE... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +diff --git a/configure.ac b/configure.ac +index 12d1f50b..14391840 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1778,6 +1778,42 @@ fi + rm -f conftest.*]) + LIBC_CONFIG_VAR([cc-pie-default], [$libc_cv_cc_pie_default]) + ++# Get Position Dependent Executable (PDE) load address to be used to ++# load static Position Independent Executable (PIE) at a known working ++# non-zero load address. This is only used by glibc tests to verify ++# that PIE and static PIE with non-zero load address work correctly. ++AC_CACHE_CHECK([PDE load address], ++ libc_cv_pde_load_address, [dnl ++cat > conftest.S <&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then ++ # Get the load address of the first PT_LOAD segment. ++ libc_cv_pde_load_address=$(LC_ALL=C $READELF -Wl conftest \ ++ | $AWK '/LOAD/ { print $3; exit 0; }') ++else ++ AC_MSG_ERROR([${CC-cc} can not create PDE]) ++fi ++rm -f conftest*]) ++LIBC_CONFIG_VAR([pde-load-address], [$libc_cv_pde_load_address]) ++ ++# Get the linker command-line option to load executable at a non-zero ++# load address. This is only used by glibc tests to verify that PIE and ++# static PIE with non-zero load address work correctly. ++LIBC_LINKER_FEATURE([-Ttext-segment=$libc_cv_pde_load_address], ++ [-Wl,-Ttext-segment=$libc_cv_pde_load_address], ++ [libc_cv_load_address_ldflag=-Wl,-Ttext-segment], ++ [libc_cv_load_address_ldflag=]) ++LIBC_CONFIG_VAR([load-address-ldflag], [$libc_cv_load_address_ldflag]) ++ + AC_MSG_CHECKING(if we can build programs as PIE) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED + # error PIE is not supported +diff --git a/elf/Makefile b/elf/Makefile +index 383c1e23..82e7ef18 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1012,6 +1012,25 @@ modules-names += tst-piemod1 + tests += tst-pie1 tst-pie2 tst-dlopen-pie tst-dlopen-tlsmodid-pie \ + tst-dlopen-self-pie + tests-pie += tst-pie1 tst-pie2 tst-dlopen-tlsmodid-pie tst-dlopen-self-pie ++ifneq (,$(load-address-ldflag)) ++tests += \ ++ tst-pie-address \ ++ # tests ++tests-pie += \ ++ tst-pie-address \ ++ # tests-pie ++LDFLAGS-tst-pie-address += $(load-address-ldflag)=$(pde-load-address) ++ifeq (yes,$(enable-static-pie)) ++tests += \ ++ tst-pie-address-static \ ++ # tests ++tests-static += \ ++ tst-pie-address-static \ ++ # tests-static ++LDFLAGS-tst-pie-address-static += \ ++ $(load-address-ldflag)=$(pde-load-address) ++endif ++endif + ifeq (yes,$(have-protected-data)) + tests += vismain + tests-pie += vismain +@@ -1875,6 +1894,7 @@ $(objpfx)tst-array5-static-cmp.out: tst-array5-static.exp \ + + CFLAGS-tst-pie1.c += $(pie-ccflag) + CFLAGS-tst-pie2.c += $(pie-ccflag) ++CFLAGS-tst-pie-address.c += $(pie-ccflag) + + $(objpfx)tst-piemod1.so: $(libsupport) + $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so +diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c +index a143ee5a..2de8a59f 100644 +--- a/elf/dl-reloc-static-pie.c ++++ b/elf/dl-reloc-static-pie.c +@@ -37,21 +37,37 @@ _dl_relocate_static_pie (void) + { + struct link_map *main_map = _dl_get_dl_main_map (); + +- /* Figure out the run-time load address of static PIE. */ +- main_map->l_addr = elf_machine_load_address (); +- +- /* Read our own dynamic section and fill in the info array. */ +- main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ()); +- ++ /* NB: elf_machine_load_address () returns the run-time load address ++ of static PIE. The l_addr field contains the difference between the ++ link-time load address in the ELF file and the run-time load address ++ in memory. We must subtract the link-time load address of static PIE, ++ which can be non-zero, when computing the l_addr field. Since static ++ PIE usually doesn't have PT_PHDR segment, use p_vaddr of the PT_LOAD ++ segment with offset == 0 as the load address of static PIE. */ ++ ElfW(Addr) file_p_vaddr = 0; + const ElfW(Phdr) *ph, *phdr = GL(dl_phdr); + size_t phnum = GL(dl_phnum); + for (ph = phdr; ph < &phdr[phnum]; ++ph) +- if (ph->p_type == PT_DYNAMIC) ++ switch (ph->p_type) + { ++ case PT_LOAD: ++ if (ph->p_offset == 0) ++ file_p_vaddr = ph->p_vaddr; ++ break; ++ case PT_DYNAMIC: + main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0; + break; ++ default: ++ break; + } + ++ /* Figure out the run-time load address of static PIE. */ ++ ElfW(Addr) l_addr = elf_machine_load_address (); ++ main_map->l_addr = l_addr - file_p_vaddr; ++ ++ /* Read our own dynamic section and fill in the info array. */ ++ main_map->l_ld = ((void *) l_addr + elf_machine_dynamic ()); ++ + elf_get_dynamic_info (main_map, false, true); + + # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC +diff --git a/elf/tst-pie-address-static.c b/elf/tst-pie-address-static.c +new file mode 100644 +index 00000000..be2831e9 +--- /dev/null ++++ b/elf/tst-pie-address-static.c +@@ -0,0 +1,19 @@ ++/* Test static PIE with non-zero load address. ++ 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 "tst-pie-address.c" +diff --git a/elf/tst-pie-address.c b/elf/tst-pie-address.c +new file mode 100644 +index 00000000..aa1ca0a9 +--- /dev/null ++++ b/elf/tst-pie-address.c +@@ -0,0 +1,28 @@ ++/* Test PIE with non-zero load address. ++ 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 ++ ++static int ++do_test (void) ++{ ++ printf ("Hello\n"); ++ return 0; ++} ++ ++#include +-- +2.27.0 + diff --git a/backport-elf-Introduce-_dl_relocate_object_no_relro.patch b/backport-elf-Introduce-_dl_relocate_object_no_relro.patch new file mode 100644 index 0000000..bf7dd93 --- /dev/null +++ b/backport-elf-Introduce-_dl_relocate_object_no_relro.patch @@ -0,0 +1,89 @@ +From f2326c2ec0a0a8db7bc7f4db8cce3002768fc3b6 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Wed, 6 Nov 2024 10:33:44 +0100 +Subject: [PATCH] elf: Introduce _dl_relocate_object_no_relro + +And make _dl_protect_relro apply RELRO conditionally. + +Reviewed-by: DJ Delorie +--- + elf/dl-reloc.c | 24 ++++++++++++++---------- + sysdeps/generic/ldsodefs.h | 7 +++++++ + 2 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c +index 1d558c1e..84bdddb2 100644 +--- a/elf/dl-reloc.c ++++ b/elf/dl-reloc.c +@@ -202,8 +202,8 @@ resolve_map (lookup_t l, struct r_scope_elem *scope[], const ElfW(Sym) **ref, + #include "dynamic-link.h" + + void +-_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], +- int reloc_mode, int consider_profiling) ++_dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[], ++ int reloc_mode, int consider_profiling) + { + struct textrels + { +@@ -242,9 +242,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + # define consider_symbind 0 + #endif + +- if (l->l_relocated) +- return; +- + /* If DT_BIND_NOW is set relocate all references in this object. We + do not do this if we are profiling, of course. */ + // XXX Correct for auditing? +@@ -342,17 +339,24 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + + textrels = textrels->next; + } +- +- /* In case we can protect the data now that the relocations are +- done, do it. */ +- if (l->l_relro_size != 0) +- _dl_protect_relro (l); + } + ++void ++_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], ++ int reloc_mode, int consider_profiling) ++{ ++ if (l->l_relocated) ++ return; ++ _dl_relocate_object_no_relro (l, scope, reloc_mode, consider_profiling); ++ _dl_protect_relro (l); ++} + + void + _dl_protect_relro (struct link_map *l) + { ++ if (l->l_relro_size == 0) ++ return; ++ + ElfW(Addr) start = ALIGN_DOWN((l->l_addr + + l->l_relro_addr), + GLRO(dl_pagesize)); +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index e8b7359b..94b32151 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -1012,6 +1012,13 @@ extern void _dl_relocate_object (struct link_map *map, + int reloc_mode, int consider_profiling) + attribute_hidden; + ++/* Perform relocation, but do not apply RELRO. Does not check ++ L->relocated. Otherwise the same as _dl_relocate_object. */ ++void _dl_relocate_object_no_relro (struct link_map *map, ++ struct r_scope_elem *scope[], ++ int reloc_mode, int consider_profiling) ++ attribute_hidden; ++ + /* Protect PT_GNU_RELRO area. */ + extern void _dl_protect_relro (struct link_map *map) attribute_hidden; + +-- +2.27.0 + diff --git a/backport-elf-Switch-to-main-malloc-after-final-ld.so-self-rel.patch b/backport-elf-Switch-to-main-malloc-after-final-ld.so-self-rel.patch new file mode 100644 index 0000000..6af7c97 --- /dev/null +++ b/backport-elf-Switch-to-main-malloc-after-final-ld.so-self-rel.patch @@ -0,0 +1,217 @@ +From c1560f3f75c0e892b5522c16f91b4e303f677094 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Wed, 6 Nov 2024 10:33:44 +0100 +Subject: [PATCH] elf: Switch to main malloc after final ld.so self-relocation + +Before commit ee1ada1bdb8074de6e1bdc956ab19aef7b6a7872 +("elf: Rework exception handling in the dynamic loader +[BZ #25486]"), the previous order called the main calloc +to allocate a shadow GOT/PLT array for auditing support. +This happened before libc.so.6 ELF constructors were run, so +a user malloc could run without libc.so.6 having been +initialized fully. One observable effect was that +environ was NULL at this point. + +It does not seem to be possible at present to trigger such +an allocation, but it seems more robust to delay switching +to main malloc after ld.so self-relocation is complete. +The elf/tst-rtld-no-malloc-audit test case fails with a +2.34-era glibc that does not have this fix. + +Reviewed-by: DJ Delorie +--- + elf/Makefile | 9 ++++ + elf/dl-support.c | 3 +- + elf/rtld.c | 26 +++++------ + elf/tst-rtld-no-malloc-audit.c | 1 + + elf/tst-rtld-no-malloc-preload.c | 1 + + elf/tst-rtld-no-malloc.c | 76 ++++++++++++++++++++++++++++++++ + 6 files changed, 100 insertions(+), 16 deletions(-) + create mode 100644 elf/tst-rtld-no-malloc-audit.c + create mode 100644 elf/tst-rtld-no-malloc-preload.c + create mode 100644 elf/tst-rtld-no-malloc.c + +diff --git a/elf/Makefile b/elf/Makefile +index cebc4a2a..ea98cba8 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -435,6 +435,9 @@ tests += \ + tst-p_align3 \ + tst-relsort1 \ + tst-ro-dynamic \ ++ tst-rtld-no-malloc \ ++ tst-rtld-no-malloc-audit \ ++ tst-rtld-no-malloc-preload \ + tst-rtld-run-static \ + tst-single_threaded \ + tst-single_threaded-pthread \ +@@ -3038,3 +3041,9 @@ CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 + CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 + CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 + endif ++ ++# Reuse an audit module which provides ample debug logging. ++tst-rtld-no-malloc-audit-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so ++ ++# Any shared object should do. ++tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so +diff --git a/elf/dl-support.c b/elf/dl-support.c +index 44a54dea..5b7f4af2 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -345,8 +345,7 @@ _dl_non_dynamic_init (void) + call_function_static_weak (_dl_find_object_init); + + /* Setup relro on the binary itself. */ +- if (_dl_main_map.l_relro_size != 0) +- _dl_protect_relro (&_dl_main_map); ++ _dl_protect_relro (&_dl_main_map); + } + + #ifdef DL_SYSINFO_IMPLEMENTATION +diff --git a/elf/rtld.c b/elf/rtld.c +index 87459ca7..558733b8 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2346,30 +2346,28 @@ dl_main (const ElfW(Phdr) *phdr, + + if (rtld_multiple_ref) + { +- /* There was an explicit ref to the dynamic linker as a shared lib. +- Re-relocate ourselves with user-controlled symbol definitions. +- +- We must do this after TLS initialization in case after this +- re-relocation, we might call a user-supplied function +- (e.g. calloc from _dl_relocate_object) that uses TLS data. */ + + /* Set up the object lookup structures. */ + _dl_find_object_init (); + +- /* The malloc implementation has been relocated, so resolving +- its symbols (and potentially calling IFUNC resolvers) is safe +- at this point. */ +- __rtld_malloc_init_real (main_map); +- + /* Likewise for the locking implementation. */ + __rtld_mutex_init (); + ++ /* Re-relocate ourselves with user-controlled symbol definitions. */ ++ + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); + +- /* Mark the link map as not yet relocated again. */ +- GL(dl_rtld_map).l_relocated = 0; +- _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); ++ _dl_relocate_object_no_relro (&GL(dl_rtld_map), main_map->l_scope, 0, 0); ++ ++ ++ /* The malloc implementation has been relocated, so resolving ++ * its symbols (and potentially calling IFUNC resolvers) is safe ++ * at this point. */ ++ __rtld_malloc_init_real (main_map); ++ ++ if (GL(dl_rtld_map).l_relro_size != 0) ++ _dl_protect_relro (&GL(dl_rtld_map)); + + rtld_timer_accum (&relocate_time, start); + } +diff --git a/elf/tst-rtld-no-malloc-audit.c b/elf/tst-rtld-no-malloc-audit.c +new file mode 100644 +index 00000000..a028377a +--- /dev/null ++++ b/elf/tst-rtld-no-malloc-audit.c +@@ -0,0 +1 @@ ++#include "tst-rtld-no-malloc.c" +diff --git a/elf/tst-rtld-no-malloc-preload.c b/elf/tst-rtld-no-malloc-preload.c +new file mode 100644 +index 00000000..a028377a +--- /dev/null ++++ b/elf/tst-rtld-no-malloc-preload.c +@@ -0,0 +1 @@ ++#include "tst-rtld-no-malloc.c" +diff --git a/elf/tst-rtld-no-malloc.c b/elf/tst-rtld-no-malloc.c +new file mode 100644 +index 00000000..5f24d4bd +--- /dev/null ++++ b/elf/tst-rtld-no-malloc.c +@@ -0,0 +1,76 @@ ++/* Test that program loading does not call malloc. ++ 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 ++ ++static void ++print (const char *s) ++{ ++ const char *end = s + strlen (s); ++ while (s < end) ++ { ++ ssize_t ret = write (STDOUT_FILENO, s, end - s); ++ if (ret <= 0) ++ _exit (2); ++ s += ret; ++ } ++} ++ ++static void __attribute__ ((noreturn)) ++unexpected_call (const char *function) ++{ ++ print ("error: unexpected call to "); ++ print (function); ++ print ("\n"); ++ _exit (1); ++} ++ ++/* These are the malloc functions implement in elf/dl-minimal.c. */ ++ ++void ++free (void *ignored) ++{ ++ unexpected_call ("free"); ++} ++ ++void * ++calloc (size_t ignored1, size_t ignored2) ++{ ++ unexpected_call ("calloc"); ++} ++ ++void * ++malloc (size_t ignored) ++{ ++ unexpected_call ("malloc"); ++} ++ ++void * ++realloc (void *ignored1, size_t ignored2) ++{ ++ unexpected_call ("realloc"); ++} ++ ++int ++main (void) ++{ ++ /* Do not use the test wrapper, to avoid spurious malloc calls from it. */ ++ return 0; ++} +-- +2.27.0 + diff --git a/glibc.spec b/glibc.spec index fa68a13..3259e48 100644 --- a/glibc.spec +++ b/glibc.spec @@ -67,7 +67,7 @@ ############################################################################## Name: glibc Version: 2.38 -Release: 43 +Release: 44 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -245,6 +245,9 @@ Patch155: 0002-nptl-Add-thread_pointer.h-for-LoongArch.patch Patch156: 0003-nptl-fix-__builtin_thread_pointer-detection-on-Loong.patch Patch157: backport-elf-avoid-jumping-over-a-needed-declaration.patch Patch158: backport-elf-Move-__rtld_malloc_init_stubs-call-into-_dl_star.patch +Patch159: backport-elf-Handle-static-PIE-with-non-zero-load-address-BZ-.patch +Patch160: backport-elf-Introduce-_dl_relocate_object_no_relro.patch +Patch161: backport-elf-Switch-to-main-malloc-after-final-ld.so-self-rel.patch #openEuler patch list Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch @@ -1466,6 +1469,11 @@ fi %endif %changelog +* Fri Dec 06 2024 shixuantong - 2.38-44 +- elf: Handle static PIE with non-zero load address +- elf: Introduce _dl_relocate_object_no_relro +- elf: Switch to main malloc after final ld.so self-relocation + * Fri Nov 29 2024 shixuantong - 2.38-43 - elf: avoid jumping over a needed declaration - elf: Move __rtld_malloc_init_stubs call into _dl_start_final -- Gitee