This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix audit testcase with IE TLS disabled (was: Re: RFC: TLSimprovements for IA32 and AMD64/EM64T)


On Sep 21, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> one additional fix for a bug that exists without my
> changes, exposed by auditing when the attribute to choose initial exec
> for libc et al is not available, but that AFAICT affects builds with
> IE enabled as well, in that the malloc hook called by calloc at the
> end of the final self-relocation of the dynamic loader accesses
> uninitialized TLS memory, that is later clobbered by the TLS
> initialization.  Oops :-)

As explained in the comment below, if we relocate ldso before setting
up TLS, the calloc call at the end of the self relocation will either
use uninitialized TLS (if libc uses IE) or crash because __tls_get_addr
returns NULL.

Index: ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* elf/rtld.c (dl_main): Run final self-relocation after
	setting up TLS.

Index: elf/rtld.c
===================================================================
RCS file: /cvs/glibc/libc/elf/rtld.c,v
retrieving revision 1.355
diff -u -p -r1.355 rtld.c
--- elf/rtld.c 26 Jun 2005 18:09:32 -0000 1.355
+++ elf/rtld.c 22 Sep 2005 00:49:46 -0000
@@ -2221,19 +2221,6 @@ ERROR: ld.so: object '%s' cannot be load
       if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
 	/* We must prepare the profiling.  */
 	_dl_start_profile ();
-
-      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.  */
-	  HP_TIMING_NOW (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);
-	  HP_TIMING_NOW (stop);
-	  HP_TIMING_DIFF (add, start, stop);
-	  HP_TIMING_ACCUM_NT (relocate_time, add);
-	}
     }
 
 #ifndef NONTLS_INIT_TP
@@ -2262,6 +2249,32 @@ ERROR: ld.so: object '%s' cannot be load
   NONTLS_INIT_TP;
 #endif
 
+  if (! prelinked && rtld_multiple_ref)
+    {
+#ifndef HP_TIMING_NONAVAIL
+      hp_timing_t start;
+      hp_timing_t stop;
+      hp_timing_t add;
+#endif
+
+      /* There was an explicit ref to the dynamic linker as a shared
+	 lib.  Re-relocate ourselves with user-controlled symbol
+	 definitions.  Do this after TLS initialization, otherwise
+	 TLS-using functions in libc that ld.so uses (e.g. the use of
+	 calloc in _dl_relocate_object, that calls a malloc hook that
+	 uses TLS if it's available) may end up using uninitialized
+	 data (if using the IE access model), or getting a NULL
+	 pointer back from __tls_get_addr because the generation
+	 counter wasn't incremented yet.  */
+      HP_TIMING_NOW (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);
+      HP_TIMING_NOW (stop);
+      HP_TIMING_DIFF (add, start, stop);
+      HP_TIMING_ACCUM_NT (relocate_time, add);
+    }
+
 #ifdef SHARED
   /* Auditing checkpoint: we have added all objects.  */
   if (__builtin_expect (GLRO(dl_naudit) > 0, 0))


-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]