This is the mail archive of the libc-hacker@sources.redhat.com 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]

[testcase] unload4 test that shows a recent regression due to dl-close.c 1.109 -> 1.110 change


Hi!

The following testcase shows a crash in the dynamic linker.
unload4mod3.so is not unloaded with its loader (unload4mod1.so),
because there was a relocation dependency:
      1031:     file=./unload4mod2.so [0];  needed by ./unload4mod4.so [0] (relocation dependency)
and
        /* We have to bump the counts for all dependencies since so far
           this object was only a normal or transitive dependency.
           Now it might be closed with _dl_close() directly.  */
        for (list = map->l_initfini; *list != NULL; ++list)
          ++(*list)->l_opencount;
loop in dl-lookup.c incremented l_opencount for unload4mod{2,4,3}.so.
When dlclosing unload4mod1.so, its l_opencount is 1, so it is unloaded,
but unload4mod{2,3,4}.so are kept.  After the
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/elf/dl-close.c.diff?cvsroot=glibc&r1=1.109&r2=1.110
change, the code that changed unload4mod3.so's l_scope[1] to its
l_searchlist is gone and thus even after unloading unload4mod1.so
(and freeing its link_map), unload4mod3.so's l_scope[1] still points
into unload4mod1.so's l_searchlist (now just freed memory).
I'm using M_PERTURB only conditionally, as the testcase happens to
crash on fedora-2_3-branch too.  If I run it with
LD_PRELOAD=libefence.so.0 EF_PROTECT_FREE=1 it crashes slightly earlier,
without efence it crashes on the same spot as
https://bugzilla.redhat.com/beta/show_bug.cgi?id=150414
crashes.

2005-03-08  Jakub Jelinek  <jakub@redhat.com>

	* elf/Makefile: Add rules to build and run unload4 test.
	* elf/unload4.c: New test.
	* elf/unload4mod1.c: New file.
	* elf/unload4mod2.c: Likewise.
	* elf/unload4mod3.c: Likewise.
	* elf/unload4mod4.c: Likewise.

--- libc/elf/Makefile.jj	2005-03-03 14:16:05.000000000 +0100
+++ libc/elf/Makefile	2005-03-08 14:06:22.268036905 +0100
@@ -85,6 +85,7 @@ distribute	:= rtld-Rules \
 		   check-textrel.c dl-sysdep.h test-dlopenrpathmod.c \
 		   tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c \
 		   unload3mod1.c unload3mod2.c unload3mod3.c unload3mod4.c \
+		   unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \
 		   tst-auditmod1.c
 
 CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
@@ -160,7 +161,7 @@ tests += loadtest restest1 preloadtest l
 	 tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
 	 tst-align2 $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
 	 tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
-	 unload3 tst-audit1 tst-global1
+	 unload3 unload4 tst-audit1 tst-global1
 #	 reldep9
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
@@ -196,7 +197,8 @@ modules-names = testobj1 testobj2 testob
 		$(modules-execstack-$(have-z-execstack)) \
 		tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
 		tst-dlmopen1mod tst-auditmod1 \
-		unload3mod1 unload3mod2 unload3mod3 unload3mod4
+		unload3mod1 unload3mod2 unload3mod3 unload3mod4 \
+		unload4mod1 unload4mod2 unload4mod3 unload4mod4
 ifeq (yes,$(have-initfini-array))
 modules-names += tst-array2dep
 endif
@@ -431,6 +433,8 @@ $(objpfx)reldep9mod3.so: $(objpfx)reldep
 $(objpfx)unload3mod1.so: $(objpfx)unload3mod3.so
 $(objpfx)unload3mod2.so: $(objpfx)unload3mod3.so
 $(objpfx)unload3mod3.so: $(objpfx)unload3mod4.so
+$(objpfx)unload4mod1.so: $(objpfx)unload4mod2.so $(objpfx)unload4mod3.so
+$(objpfx)unload4mod2.so: $(objpfx)unload4mod4.so $(objpfx)unload4mod3.so
 
 LDFLAGS-tst-tlsmod5.so = -nostdlib
 LDFLAGS-tst-tlsmod6.so = -nostdlib
@@ -471,6 +475,7 @@ circlemod3a.so-no-z-defs = yes
 reldep8mod2.so-no-z-defs = yes
 reldep9mod1.so-no-z-defs = yes
 unload3mod4.so-no-z-defs = yes
+unload4mod1.so-no-z-defs = yes
 
 # filtmod1.so has a special rule
 $(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
@@ -691,6 +696,9 @@ $(objpfx)unload3: $(libdl)
 $(objpfx)unload3.out: $(objpfx)unload3mod1.so $(objpfx)unload3mod2.so \
 		      $(objpfx)unload3mod3.so $(objpfx)unload3mod4.so
 
+$(objpfx)unload4: $(libdl)
+$(objpfx)unload4.out: $(objpfx)unload4mod1.so $(objpfx)unload4mod3.so
+
 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/unload4.c.jj	2005-03-08 13:53:05.196954197 +0100
+++ libc/elf/unload4.c	2005-03-08 13:54:08.207735948 +0100
@@ -0,0 +1,48 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <malloc.h>
+
+int
+main (void)
+{
+#ifdef M_PERTURB
+  mallopt (M_PERTURB, 0xaa);
+#endif
+
+  void *h;
+  int (*fn) (int);
+  h = dlopen ("unload4mod1.so", RTLD_LAZY);
+  if (h == NULL)
+    {
+      puts ("1st dlopen failed");
+      return 1;
+    }
+  fn = dlsym (h, "foo");
+  if (fn == NULL)
+    {
+      puts ("dlsym failed");
+      return 1;
+    }
+  int n = fn (10);
+  if (n != 28)
+    {
+      printf ("foo (10) returned %d != 28\n", n);
+      return 1;
+    }
+  dlclose (h);
+  h = dlopen ("unload4mod3.so", RTLD_LAZY);
+  fn = dlsym (h, "mod3fn2");
+  if (fn == NULL)
+    {
+      puts ("second dlsym failed");
+      return 1;
+    }
+  n = fn (10);
+  if (n != 22)
+    {
+      printf ("mod3fn2 (10) returned %d != 22\n", n);
+      return 1;
+    }
+  dlclose (h);
+  return 0;
+}
--- libc/elf/unload4mod1.c.jj	2005-03-08 13:53:05.196954197 +0100
+++ libc/elf/unload4mod1.c	2005-03-08 13:22:09.000000000 +0100
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+extern int bar (int);
+
+int
+foo (int x)
+{
+  puts ("in foo");
+  return bar (x / 2) + 2;
+}
--- libc/elf/unload4mod2.c.jj	2005-03-08 13:53:05.196954197 +0100
+++ libc/elf/unload4mod2.c	2005-03-08 13:19:18.000000000 +0100
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+baz (int x)
+{
+  puts ("in baz");
+  return x * 4;
+}
--- libc/elf/unload4mod3.c.jj	2005-03-08 13:53:05.196954197 +0100
+++ libc/elf/unload4mod3.c	2005-03-08 14:03:14.220520033 +0100
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int
+__attribute__((noinline))
+mod3fn1 (int x)
+{
+  puts ("in mod3fn1");
+  return x + 6;
+}
+
+int
+mod3fn2 (int x)
+{
+  puts ("in mod3fn2");
+  return mod3fn1 (x / 2) * 2;
+}
--- libc/elf/unload4mod4.c.jj	2005-03-08 13:53:05.196954197 +0100
+++ libc/elf/unload4mod4.c	2005-03-08 13:23:06.000000000 +0100
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+__attribute__((noinline))
+baz (int x)
+{
+  abort ();
+}
+
+int
+bar (int x)
+{
+  puts ("in bar");
+  return baz (x + 1) + 2;
+}

	Jakub


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