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]

[patch] fix uninitialized variable in dynamic linker


When we were testing glibc 2.21 here, we were getting some mysterious dynamic linking failures on MIPS due to the recent-ish changes for that target to ignore objects with incompatible FP ABIs. On further investigation, it turned out that the dynamic linker's own entry in the link map had an invalid l_mach.fpabi value. I tracked this down to failure to initialize that field in the stack-allocated bootstrap_map structure in _dl_start; _dl_start_final was then happily copying the uninitialized l_mach value into the real map data structure.

The attached patch zero-initializes the entire bootstrap_map data structure. I thought this was better than selectively initializing specific fields since it future-proofs the code against similar errors involving other fields that might be added (or used) in the future.

I've verified that this fixes the 2.21 MIPS problems we saw. Is this patch OK for mainline head, or is further testing required?

-Sandra

2015-03-21  Sandra Loosemore  <sandra@codesourcery.com>

	* elf/rtld.c (_dl_start): Zero-initialize the entire bootstrap_map
	structure.
Index: elf/rtld.c
===================================================================
--- elf/rtld.c	(revision 447026)
+++ elf/rtld.c	(working copy)
@@ -356,24 +356,26 @@ _dl_start (void *arg)
     HP_TIMING_NOW (start_time);
 #else
     HP_TIMING_NOW (info.start_time);
 #endif
 
-  /* Partly clean the `bootstrap_map' structure up.  Don't use
+  /* Zero-initialize the `bootstrap_map' structure.  Don't use
      `memset' since it might not be built in or inlined and we cannot
      make function calls at this point.  Use '__builtin_memset' if we
      know it is available.  We do not have to clear the memory if we
      do not have to use the temporary bootstrap_map.  Global variables
      are initialized to zero by default.  */
 #ifndef DONT_USE_BOOTSTRAP_MAP
 # ifdef HAVE_BUILTIN_MEMSET
-  __builtin_memset (bootstrap_map.l_info, '\0', sizeof (bootstrap_map.l_info));
+  __builtin_memset (&bootstrap_map, '\0', sizeof (struct link_map));
 # else
-  for (size_t cnt = 0;
-       cnt < sizeof (bootstrap_map.l_info) / sizeof (bootstrap_map.l_info[0]);
-       ++cnt)
-    bootstrap_map.l_info[cnt] = 0;
+  {
+    char *p = (char *) &bootstrap_map;
+    char *pend = p + sizeof (struct link_map);
+    while (p < pend)
+      *(p++) = '\0';
+  }
 # endif
 #endif
 
   /* Figure out the run-time load address of the dynamic linker itself.  */
   bootstrap_map.l_addr = elf_machine_load_address ();

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