This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[patch] fix uninitialized variable in dynamic linker
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Sat, 21 Mar 2015 15:47:19 -0600
- Subject: [patch] fix uninitialized variable in dynamic linker
- Authentication-results: sourceware.org; auth=none
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 ();