From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1944) id 9EA15385481A; Thu, 14 Jan 2021 11:12:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9EA15385481A Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Szabolcs Nagy To: glibc-cvs@sourceware.org Subject: [glibc/nsz/bug27072] csu: Move static pie self relocation later [BZ #27072] X-Act-Checkin: glibc X-Git-Author: Szabolcs Nagy X-Git-Refname: refs/heads/nsz/bug27072 X-Git-Oldrev: ba39a496a5cce5f1a23630b6a335898aab6255fd X-Git-Newrev: 413ed92e774ac0b8056b5e7d72bf66b5eab03801 Message-Id: <20210114111222.9EA15385481A@sourceware.org> Date: Thu, 14 Jan 2021 11:12:22 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2021 11:12:22 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=413ed92e774ac0b8056b5e7d72bf66b5eab03801 commit 413ed92e774ac0b8056b5e7d72bf66b5eab03801 Author: Szabolcs Nagy Date: Wed Jan 6 14:28:02 2021 +0000 csu: Move static pie self relocation later [BZ #27072] IFUNC resolvers may depend on tunables and cpu feature setup so move static pie self relocation after those. It is hard to guarantee that the ealy startup code does not rely on relocations so this is a bit fragile. It would be more robust to handle RELATIVE relocs early and only IRELATIVE relocs later, but the current relocation processing code cannot do that. The early startup code before relocation processing includes _dl_aux_init (auxvec); __libc_init_secure (); __tunables_init (__environ); ARCH_INIT_CPU_FEATURES (); These are simple enough that RELATIVE relocs can be avoided. __ehdr_start may require RELATIVE relocation so it was moved later, fortunately ehdr and phdr are not used in the early code. Fixes bug 27072. Diff: --- csu/libc-start.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/csu/libc-start.c b/csu/libc-start.c index db859c3bed..fb64cdb2c9 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -142,8 +142,6 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), int result; #ifndef SHARED - _dl_relocate_static_pie (); - char **ev = &argv[argc + 1]; __environ = ev; @@ -165,24 +163,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } # endif _dl_aux_init (auxvec); - if (GL(dl_phdr) == NULL) # endif - { - /* Starting from binutils-2.23, the linker will define the - magic symbol __ehdr_start to point to our own ELF header - if it is visible in a segment that also includes the phdrs. - So we can set up _dl_phdr and _dl_phnum even without any - information from auxv. */ - - extern const ElfW(Ehdr) __ehdr_start - __attribute__ ((weak, visibility ("hidden"))); - if (&__ehdr_start != NULL) - { - assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr)); - GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff; - GL(dl_phnum) = __ehdr_start.e_phnum; - } - } /* Initialize very early so that tunables can use it. */ __libc_init_secure (); @@ -191,6 +172,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), ARCH_INIT_CPU_FEATURES (); + /* Do static pie self relocation after tunables and cpu features + are setup for ifunc resolvers. Before this point relocations + must be avoided. */ + _dl_relocate_static_pie (); + /* Perform IREL{,A} relocations. */ ARCH_SETUP_IREL (); @@ -202,6 +188,26 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), hwcap and platform fields available in the TCB. */ ARCH_APPLY_IREL (); +# ifdef HAVE_AUX_VECTOR + if (GL(dl_phdr) == NULL) +# endif + { + /* Starting from binutils-2.23, the linker will define the + magic symbol __ehdr_start to point to our own ELF header + if it is visible in a segment that also includes the phdrs. + So we can set up _dl_phdr and _dl_phnum even without any + information from auxv. */ + + extern const ElfW(Ehdr) __ehdr_start + __attribute__ ((weak, visibility ("hidden"))); + if (&__ehdr_start != NULL) + { + assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr)); + GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff; + GL(dl_phnum) = __ehdr_start.e_phnum; + } + } + /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); # ifdef THREAD_SET_STACK_GUARD