about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Versions3
-rw-r--r--elf/dl-deps.c3
-rw-r--r--elf/dl-error.c8
-rw-r--r--elf/dl-libc.c2
-rw-r--r--elf/dl-open.c3
-rw-r--r--elf/rtld.c3
6 files changed, 18 insertions, 4 deletions
diff --git a/elf/Versions b/elf/Versions
index a7c5a780f6..bb8b5f5982 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -56,5 +56,8 @@ ld {
 
     # this is defined in ld.so and overridden by libc
     _dl_init_first;
+
+    # variables used elsewhere
+    _dl_out_of_memory;
   }
 }
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 7c7b4b6672..1d3779f822 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -295,7 +295,8 @@ _dl_map_object_deps (struct link_map *map,
 		      {
 			/* We are not interested in the error message.  */
 			assert (errstring != NULL);
-			free ((char *) errstring);
+			if (errstring != _dl_out_of_memory)
+			  free ((char *) errstring);
 
 			/* Simply ignore this error and continue the work.  */
 			continue;
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 88ab8e9519..959e1de202 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -45,6 +45,12 @@ __libc_tsd_define (static, DL_ERROR)
 #define tsd_setspecific(data)	__libc_tsd_set (DL_ERROR, (data))
 
 
+/* This message we return as a last resort.  We define the string in a
+   variable since we have to avoid freeing it and so have to enable
+   a pointer comparison.  See below and in dlfcn/dlerror.c.  */
+const char _dl_out_of_memory[] = "out of memory";
+
+
 /* This points to a function which is called when an continuable error is
    received.  Unlike the handling of `catch' this function may return.
    The arguments will be the `errstring' and `objname'.
@@ -72,6 +78,8 @@ _dl_signal_error (int errcode, const char *objname, const char *errstring)
 	 stack.  The object name is always a string constant.  */
       lcatch->objname = objname;
       lcatch->errstring = strdup (errstring);
+      if (lcatch->errstring == NULL)
+	lcatch->errstring = _dl_out_of_memory;
       longjmp (lcatch->env, errcode ?: -1);
     }
   else
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index 38774e50a0..992a52e699 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -42,7 +42,7 @@ dlerror_run (void (*operate) (void *), void *args)
   (void) _dl_catch_error (&objname, &last_errstring, operate, args);
 
   result = last_errstring != NULL;
-  if (result)
+  if (result && last_errstring != _dl_out_of_memory)
     free ((char *) last_errstring);
 
   return result;
diff --git a/elf/dl-open.c b/elf/dl-open.c
index e5628b6f06..680377be0a 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -329,7 +329,8 @@ _dl_open (const char *file, int mode, const void *caller)
       /* Make a local copy of the error string so that we can release the
 	 memory allocated for it.  */
       local_errstring = strdupa (errstring);
-      free ((char *) errstring);
+      if (errstring != _dl_out_of_memory)
+	free ((char *) errstring);
 
       /* Reraise the error.  */
       _dl_signal_error (errcode, objname, local_errstring);
diff --git a/elf/rtld.c b/elf/rtld.c
index 68c516d4bc..1db96999ea 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -506,7 +506,8 @@ of this helper program; chances are you did not intend to run this program.\n\
 	  (void) _dl_catch_error (&objname, &err_str, map_doit, &args);
 	  if (__builtin_expect (err_str != NULL, 0))
 	    {
-	      free ((char *) err_str);
+	      if (err_str != _dl_out_of_memory)
+		free ((char *) err_str);
 	      _exit (EXIT_FAILURE);
 	    }
 	}