From patchwork Sat Mar 21 21:47:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 5749 Received: (qmail 123727 invoked by alias); 21 Mar 2015 21:48:08 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 123714 invoked by uid 89); 21 Mar 2015 21:48:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Message-ID: <550DE6E7.5030900@codesourcery.com> Date: Sat, 21 Mar 2015 15:47:19 -0600 From: Sandra Loosemore User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: Subject: [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 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 ();