!940 sync some patches for elf
Merge pull request !940 from 桐小哥/openEuler-24.03-LTS
This commit is contained in:
commit
6acf3f9227
@ -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
|
||||
|
||||
|
||||
@ -0,0 +1,306 @@
|
||||
From e7b553272196e6175b8a15f807cb59217ba2843a Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
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 <hjl.tools@gmail.com>
|
||||
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
---
|
||||
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 <<EOF
|
||||
+.globl _start
|
||||
+_start:
|
||||
+.globl __start
|
||||
+__start:
|
||||
+EOF
|
||||
+if test $libc_cv_cc_pie_default = yes; then
|
||||
+ pde_ld_flags="-no-pie"
|
||||
+fi
|
||||
+if ${CC-cc} $pde_ld_flags $CFLAGS $CPPFLAGS $LDFLAGS \
|
||||
+ -nostartfiles -nostdlib $no_ssp \
|
||||
+ -o conftest conftest.S 1>&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 <<EOF
|
||||
+int _start (void) { return 42; }
|
||||
+EOF
|
||||
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
|
||||
+ -Wl,-Ttext-segment=$libc_cv_pde_load_address -nostdlib -nostartfiles
|
||||
+ -fPIC -shared -o conftest.so conftest.c
|
||||
+ 1>&5'
|
||||
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&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 <<EOF
|
||||
+.globl _start
|
||||
+_start:
|
||||
+.globl __start
|
||||
+__start:
|
||||
+EOF
|
||||
+if test $libc_cv_cc_pie_default = yes; then
|
||||
+ pde_ld_flags="-no-pie"
|
||||
+fi
|
||||
+if ${CC-cc} $pde_ld_flags $CFLAGS $CPPFLAGS $LDFLAGS \
|
||||
+ -nostartfiles -nostdlib $no_ssp \
|
||||
+ -o conftest conftest.S 1>&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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ printf ("Hello\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
--
|
||||
2.27.0
|
||||
|
||||
89
backport-elf-Introduce-_dl_relocate_object_no_relro.patch
Normal file
89
backport-elf-Introduce-_dl_relocate_object_no_relro.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From f2326c2ec0a0a8db7bc7f4db8cce3002768fc3b6 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
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 <dj@redhat.com>
|
||||
---
|
||||
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
|
||||
|
||||
@ -0,0 +1,217 @@
|
||||
From c1560f3f75c0e892b5522c16f91b4e303f677094 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
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 <dj@redhat.com>
|
||||
---
|
||||
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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+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
|
||||
|
||||
10
glibc.spec
10
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 <shixuantong@huawei.com> - 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 <shixuantong@huawei.com> - 2.38-43
|
||||
- elf: avoid jumping over a needed declaration
|
||||
- elf: Move __rtld_malloc_init_stubs call into _dl_start_final
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user