This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Test for a dlclose failure


Hi!

This testcase segfaults in ld.so.  When unload7mod2.so is loaded,
it is added to unload7mod1.so's l_scope, but when it is dlclosed,
nothing removes it from that scope.
In _dl_close:
      else if (imap->l_type == lt_loaded)		<= this condition is true
        {
          if (imap->l_searchlist.r_list == NULL		<= this one is not
              && imap->l_initfini != NULL)		<= this one is true
            {
and therefore imap->l_scope isn't walked and adjusted.

2006-09-16  Jakub Jelinek  <jakub@redhat.com>

	* elf/Makefile: Add rules to build and run unload7 test.
	* elf/unload7.c: New test.
	* elf/unload7mod1.c: New file.
	* elf/unload7mod2.c: New file.

--- libc/elf/Makefile.jj	2006-08-25 11:01:23.000000000 +0200
+++ libc/elf/Makefile	2006-09-16 20:19:06.000000000 +0200
@@ -87,6 +87,7 @@ distribute	:= rtld-Rules \
 		   unload3mod1.c unload3mod2.c unload3mod3.c unload3mod4.c \
 		   unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \
 		   unload6mod1.c unload6mod2.c unload6mod3.c \
+		   unload7mod1.c unload7mod2.c \
 		   tst-auditmod1.c tst-audit.sh \
 		   order2mod1.c order2mod2.c order2mod3.c order2mod4.c \
 		   tst-stackguard1.c tst-stackguard1-static.c \
@@ -168,7 +169,7 @@ tests += loadtest restest1 preloadtest l
 	 tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
 	 tst-dlmodcount tst-dlopenrpath tst-deep1 \
 	 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
-	 unload3 unload4 unload5 unload6 tst-global1 order2 \
+	 unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \
 	 tst-audit1 tst-audit2 \
 	 tst-stackguard1 tst-addr1
 #	 reldep9
@@ -211,6 +212,7 @@ modules-names = testobj1 testobj2 testob
 		unload3mod1 unload3mod2 unload3mod3 unload3mod4 \
 		unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
 		unload6mod1 unload6mod2 unload6mod3 \
+		unload7mod1 unload7mod2 \
 		order2mod1 order2mod2 order2mod3 order2mod4
 ifeq (yes,$(have-initfini-array))
 modules-names += tst-array2dep tst-array5dep
@@ -455,6 +457,8 @@ $(objpfx)unload4mod2.so: $(objpfx)unload
 $(objpfx)unload6mod1.so: $(libdl)
 $(objpfx)unload6mod2.so: $(libdl)
 $(objpfx)unload6mod3.so: $(libdl)
+$(objpfx)unload7mod1.so: $(libdl)
+$(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so
 
 LDFLAGS-tst-tlsmod5.so = -nostdlib
 LDFLAGS-tst-tlsmod6.so = -nostdlib
@@ -732,6 +736,10 @@ $(objpfx)unload6: $(libdl)
 $(objpfx)unload6.out: $(objpfx)unload6mod1.so $(objpfx)unload6mod2.so \
 		      $(objpfx)unload6mod3.so
 
+$(objpfx)unload7: $(libdl)
+$(objpfx)unload7.out: $(objpfx)unload7mod1.so $(objpfx)unload7mod2.so
+unload7-ENV = MALLOC_PERTURB_=85
+
 ifdef libdl
 $(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
 $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
--- libc/elf/unload7.c.jj	2006-09-16 19:58:48.000000000 +0200
+++ libc/elf/unload7.c	2006-09-16 20:03:31.000000000 +0200
@@ -0,0 +1,39 @@
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+  void *h = dlopen ("unload7mod1.so", RTLD_LAZY);
+  if (h == NULL)
+    {
+      puts ("dlopen unload7mod1.so failed");
+      return 1;
+    }
+
+  int (*fn) (void);
+  fn = dlsym (h, "foo");
+  if (fn == NULL)
+    {
+      puts ("dlsym failed");
+      return 1;
+    }
+
+  int ret = 0;
+  if (fn () == 0)
+    ++ret;
+
+  void *h2 = dlopen ("unload7mod2.so", RTLD_LAZY);
+  if (h2 == NULL)
+    {
+      puts ("dlopen unload7mod1.so failed");
+      return 1;
+    }
+  dlclose (h2);
+
+  if (fn () == 0)
+    ++ret;
+
+  dlclose (h);
+  return ret;
+}
--- libc/elf/unload7mod1.c.jj	2006-09-16 20:04:13.000000000 +0200
+++ libc/elf/unload7mod1.c	2006-09-16 20:06:26.000000000 +0200
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+foo (int i)
+{
+  if (dlsym (RTLD_DEFAULT, "unload7_nonexistent_symbol") == NULL)
+    return 1;
+  puts ("dlsym returned non-NULL");
+  return 0;
+}
--- libc/elf/unload7mod2.c.jj	2006-09-16 20:06:51.000000000 +0200
+++ libc/elf/unload7mod2.c	2006-09-16 20:06:43.000000000 +0200
@@ -0,0 +1 @@
+int x;

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]