[v4,fixed] csu: Move static pie self relocation later [BZ #27072]

Message ID 20210119160626.14151-1-szabolcs.nagy@arm.com
State Superseded
Headers
Series [v4,fixed] csu: Move static pie self relocation later [BZ #27072] |

Commit Message

Szabolcs Nagy Jan. 19, 2021, 4:06 p.m. UTC
  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 up to relocation processing includes

  _dl_aux_init (auxvec);
  __libc_init_secure ();
  __tunables_init (__environ);
  ARCH_INIT_CPU_FEATURES ();
  _dl_relocate_static_pie ();

These are simple enough that RELATIVE relocs can be avoided.

The following steps include

  ARCH_SETUP_IREL ();
  ARCH_SETUP_TLS ();
  ARCH_APPLY_IREL ();

__ehdr_start may require RELATIVE relocation so it was moved
after relocation processing but before tls setup which needs
the program headers. This also means that targets that need
ifunc resolution to be after tls setup cannot support static
pie without splitting RELATIVE and IRELATIVE processing (or
removing some of the dependencies between these steps).

Fixes bug 27072.
---
pushed a new patchset with this fixed to nsz/bug27072
and dropped the x86 test that is under discussion.

Note: it's not clear that this is the right approach,
the options considered:

(1) avoid relative relocs by making symbols hidden in some files,
(2) avoid relative relocs by marking some objects hidden,
(3) do relative relocs early and irelative later

for now (1) seemed simplest, but as noted in the commit message
if relative and irelative are processed together that is a bit
awkward (requires various workarounds for i386 that cannot mark
all symbols hidden and means inflexible dependencies between
operations that may be circular if ifuncs rely on tls).


 csu/libc-start.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)
  

Patch

diff --git a/csu/libc-start.c b/csu/libc-start.c
index 1e90dcb0a7..3239125202 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -146,8 +146,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;
@@ -169,6 +167,24 @@  LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
   }
 #  endif
   _dl_aux_init (auxvec);
+# endif
+
+  /* Initialize very early so that tunables can use it.  */
+  __libc_init_secure ();
+
+  __tunables_init (__environ);
+
+  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 ();
+
+# ifdef HAVE_AUX_VECTOR
   if (GL(dl_phdr) == NULL)
 # endif
     {
@@ -188,16 +204,6 @@  LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
         }
     }
 
-  /* Initialize very early so that tunables can use it.  */
-  __libc_init_secure ();
-
-  __tunables_init (__environ);
-
-  ARCH_INIT_CPU_FEATURES ();
-
-  /* Perform IREL{,A} relocations.  */
-  ARCH_SETUP_IREL ();
-
   /* The stack guard goes into the TCB, so initialize it early.  */
   ARCH_SETUP_TLS ();