[PATCH] Fix segfault in open_path

Jakub Jelinek jakub@redhat.com
Mon Feb 7 10:49:00 GMT 2005


Hi!

Running:
#include <dlfcn.h>
#include <unistd.h>

int main (void)
{
  chroot ("/tmp/foobar");
  dlopen ("libnss_compat.so.2", RTLD_LAZY);
}
as root after rm -rf /tmp/foobar; mkdir /tmp/foobar
results in a segfault.  The problem is that rtld_search_dirs are
attribute_relro, but open_path if it doesn't find any of the standard
search directories wants to clear it.
One solution would be to remove attribute_relro from rtld_search_dirs,
but that's a variable that IMHO should be protected from changing,
so this patch just avoids writing into it instead.  Because standard
search paths are almost always present and only in very rare situations
like this chroot testcase none of them is, I think letting ld.so
in this case cycle through open_path and see that all dirs in it are
nonexisting is not a big deal.  rtld_search_dirs.malloced is 0, so
it is not freed either.

2005-01-07  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-load.c (open_path): If rtld_search_dirs is in RELRO segment,
	avoid writing to it if none of the standard search directories
	exist.

--- libc/elf/dl-load.c.jj	2005-01-19 14:12:38.000000000 +0100
+++ libc/elf/dl-load.c	2005-02-07 11:24:58.611074914 +0100
@@ -1876,7 +1876,12 @@ open_path (const char *name, size_t name
 	 must not be freed using the general free() in libc.  */
       if (sps->malloced)
 	free (sps->dirs);
-      sps->dirs = (void *) -1;
+#ifdef HAVE_Z_RELRO
+      /* rtld_search_dirs is attribute_relro, therefore avoid writing
+	 into it.  */
+      if (sps != &rtld_search_dirs)
+#endif
+	sps->dirs = (void *) -1;
     }
 
   return -1;

	Jakub



More information about the Libc-hacker mailing list