about summary refs log tree commit diff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2015-01-21 01:51:10 -0500
committerCarlos O'Donell <carlos@systemhalted.org>2015-01-21 01:51:10 -0500
commitccdb048df457d581f6ac7ede8b0c7a593a891dfa (patch)
tree9f87447c45093fb2ded95c982e68c9e6e886129c /elf/dl-load.c
parent042e1521c794a945edc43b5bfa7e69ad70420524 (diff)
downloadglibc-ccdb048df457d581f6ac7ede8b0c7a593a891dfa.tar.gz
glibc-ccdb048df457d581f6ac7ede8b0c7a593a891dfa.tar.xz
glibc-ccdb048df457d581f6ac7ede8b0c7a593a891dfa.zip
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
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r--elf/dl-load.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index d6726b627f..73174aa424 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -2051,7 +2051,7 @@ _dl_map_object (struct link_map *loader, const char *name,
 	{
 	  /* Check the list of libraries in the file /etc/ld.so.cache,
 	     for compatibility with Linux's ldconfig program.  */
-	  const char *cached = _dl_load_cache_lookup (name);
+	  char *cached = _dl_load_cache_lookup (name);
 
 	  if (cached != NULL)
 	    {
@@ -2075,6 +2075,7 @@ _dl_map_object (struct link_map *loader, const char *name,
 		      if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0)
 			{
 			  /* The prefix matches.  Don't use the entry.  */
+			  free (cached);
 			  cached = NULL;
 			  break;
 			}
@@ -2092,14 +2093,9 @@ _dl_map_object (struct link_map *loader, const char *name,
 				    LA_SER_CONFIG, mode, &found_other_class,
 				    false);
 		  if (__glibc_likely (fd != -1))
-		    {
-		      realname = __strdup (cached);
-		      if (realname == NULL)
-			{
-			  __close (fd);
-			  fd = -1;
-			}
-		    }
+		    realname = cached;
+		  else
+		    free (cached);
 		}
 	    }
 	}