1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

Fix recursive dlopen.

The ability to recursively call dlopen is useful for malloc
implementations that wish to load other dynamic modules that
implement reentrant/AS-safe functions to use in their own
implementation.

Given that a user malloc implementation may be called by an
ongoing dlopen to allocate memory the user malloc
implementation interrupts dlopen and if it calls dlopen again
that's a reentrant call.

This patch fixes the issues with the ld.so.cache mapping
and the _r_debug assertion which prevent this from working
as expected.

See:
https://sourceware.org/ml/libc-alpha/2014-12/msg00446.html
This commit is contained in:
Carlos O'Donell
2015-01-21 01:51:10 -05:00
parent 042e1521c7
commit ccdb048df4
10 changed files with 222 additions and 21 deletions

View File

@ -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)
{
@ -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