X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=elf%2Fdl-cache.c;h=dec49bc0f20109705261e9e821327e4c9c4cb88d;hb=ccdb048df457d581f6ac7ede8b0c7a593a891dfa;hp=d36623f09e87f98d0c548f63b24b68ab0f17d0c1;hpb=d4697bc93dc27a7bbf275ce7dd351bb1bfcf28de;p=platform%2Fupstream%2Fglibc.git diff --git a/elf/dl-cache.c b/elf/dl-cache.c index d36623f..dec49bc 100644 --- a/elf/dl-cache.c +++ b/elf/dl-cache.c @@ -1,5 +1,5 @@ /* Support for reading /etc/ld.so.cache files written by Linux ldconfig. - Copyright (C) 1996-2014 Free Software Foundation, Inc. + Copyright (C) 1996-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -65,7 +65,7 @@ do \ \ /* Actually compare the entry with the key. */ \ cmpres = _dl_cache_libcmp (name, cache_data + key); \ - if (__builtin_expect (cmpres == 0, 0)) \ + if (__glibc_unlikely (cmpres == 0)) \ { \ /* Found it. LEFT now marks the last entry for which we \ know the name is correct. */ \ @@ -174,9 +174,12 @@ _dl_cache_libcmp (const char *p1, const char *p2) /* Look up NAME in ld.so.cache and return the file name stored there, or null if none is found. The cache is loaded if it was not already. If loading - the cache previously failed there will be no more attempts to load it. */ - -const char * + the cache previously failed there will be no more attempts to load it. + The caller is responsible for freeing the returned string. The ld.so.cache + may be unmapped at any time by a completing recursive dlopen and + this function must take care that it does not return references to + any data in the mapping. */ +char * internal_function _dl_load_cache_lookup (const char *name) { @@ -187,7 +190,7 @@ _dl_load_cache_lookup (const char *name) const char *best; /* Print a message if the loading of libs is traced. */ - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)) + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE); if (cache == NULL) @@ -289,7 +292,17 @@ _dl_load_cache_lookup (const char *name) && best != NULL) _dl_debug_printf (" trying file=%s\n", best); - return best; + if (best == NULL) + return NULL; + + /* The double copy is *required* since malloc may be interposed + and call dlopen itself whose completion would unmap the data + we are accessing. Therefore we must make the copy of the + mapping data without using malloc. */ + char *temp; + temp = alloca (strlen (best) + 1); + strcpy (temp, best); + return strdup (temp); } #ifndef MAP_COPY