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]

[PATCH] Fix dl_close l_reldeps handling


Hi!

The attached testcase segfaults with current glibc. I guess it is quite
obvious, the issue is that _dl_close uses `map' instead of `imap' pointer,
which
a) after map is freed points to freed memory
b) even if that does work, we may add the same reldeps list several
   times and some not at all, which means that some libraries may be
   _dl_closed several times and if they get to zero l_opencount before
   last _dl_close we have a problem again.

2001-05-22  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-close.c (_dl_close): Save imap->l_reldeps, not
	map->l_reldeps.

	* elf/Makefile (distribute): Add reldep4mod[1234].c.
	(tests): Add reldep4.
	(modules-names): Add reldep4mod[1234].
	(reldep4mod1.so, reldep4mod2.so, reldep4, reldep4.out): New rules.
	* elf/reldep4.c: New file.
	* elf/reldep4mod1.c: Likewise.
	* elf/reldep4mod2.c: Likewise.
	* elf/reldep4mod3.c: Likewise.
	* elf/reldep4mod4.c: Likewise.

--- libc/elf/dl-close.c.jj	Tue May 22 11:09:07 2001
+++ libc/elf/dl-close.c	Tue May 22 11:54:45 2001
@@ -224,8 +224,8 @@ _dl_close (void *_map)
 	      struct reldep_list *newrel;
 
 	      newrel = (struct reldep_list *) alloca (sizeof (*reldeps));
-	      newrel->rellist = map->l_reldeps;
-	      newrel->nrellist = map->l_reldepsact;
+	      newrel->rellist = imap->l_reldeps;
+	      newrel->nrellist = imap->l_reldepsact;
 	      newrel->next = reldeps;
 
 	      reldeps = newrel;
--- libc/elf/Makefile.jj	Tue May 22 11:09:04 2001
+++ libc/elf/Makefile	Tue May 22 12:11:17 2001
@@ -53,6 +53,7 @@ distribute	:= $(rtld-routines:=.c) dynam
 		   nodlopenmod.c nodelete.c nodelmod1.c nodelmod2.c \
 		   nodelmod3.c nodelmod4.c nodlopen.c dl-osinfo.h \
 		   reldepmod1.c reldepmod2.c reldepmod3.c reldepmod4.c \
+		   reldep4mod1.c reldep4mod2.c reldep4mod3.c reldep4mod4.c \
 		   nextmod1.c nextmod2.c pathoptobj.c tst-pathopt.sh \
 		   neededobj1.c neededobj2.c neededobj3.c neededobj4.c \
 		   neededobj5.c neededobj6.c firstobj.c \
@@ -99,7 +100,7 @@ endif
 ifeq (yes,$(build-shared))
 tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	constload1 order $(tests-vis-$(have-protected)) noload filter unload \
-	reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
+	reldep reldep2 reldep3 reldep4 next $(tests-nodelete-$(have-z-nodelete)) \
 	$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
 	neededtest3 neededtest4 unload2 lateglobal initfirst global
 test-srcs = tst-pathopt
@@ -113,6 +114,7 @@ modules-names = testobj1 testobj2 testob
 		$(modules-nodelete-$(have-z-nodelete)) \
 		$(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \
 		reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
+		reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \
 		neededobj1 neededobj2 neededobj3 neededobj4 \
 		neededobj5 neededobj6 firstobj globalmod1 \
 		unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj
@@ -274,6 +276,8 @@ $(objpfx)unload2mod.so: $(objpfx)unload2
 $(objpfx)ltglobmod2.so: $(libdl)
 $(objpfx)firstobj.so: $(shared-thread-library)
 $(objpfx)globalmod1.so: $(libdl)
+$(objpfx)reldep4mod1.so: $(objpfx)reldep4mod3.so
+$(objpfx)reldep4mod2.so: $(objpfx)reldep4mod4.so
 
 # filtmod1.so has a special rule
 $(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
@@ -381,6 +385,9 @@ $(objpfx)reldep2.out: $(objpfx)reldepmod
 
 $(objpfx)reldep3: $(libdl)
 $(objpfx)reldep3.out: $(objpfx)reldepmod1.so $(objpfx)reldepmod4.so
+
+$(objpfx)reldep4: $(libdl)
+$(objpfx)reldep4.out: $(objpfx)reldep4mod1.so $(objpfx)reldep4mod2.so
 
 $(objpfx)next: $(objpfx)nextmod1.so $(objpfx)nextmod2.so $(libdl)
 
--- libc/elf/reldep4.c.jj	Tue May 22 12:05:19 2001
+++ libc/elf/reldep4.c	Tue May 22 12:25:59 2001
@@ -0,0 +1,40 @@
+#include <dlfcn.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main()
+{
+  int i;
+  void *h1, *h2;
+
+  mtrace ();
+
+  for (i = 0; i < 3; i++)
+    {
+      h1 = dlopen ("reldep4mod1.so", RTLD_NOW | RTLD_GLOBAL);
+      if (h1 == NULL)
+	{
+	  printf ("cannot open reldep4mod1.so: %s\n", dlerror ());
+	  exit (1);
+	}
+      h2 = dlopen ("reldep4mod2.so", RTLD_NOW | RTLD_GLOBAL);
+      if (h2 == NULL)
+	{
+	  printf ("cannot open reldep4mod2.so: %s\n", dlerror ());
+	  exit (1);
+	}
+      if (dlclose (h1) != 0)
+	{
+	  printf ("closing h1 failed: %s\n", dlerror ());
+	  exit (1);
+	}
+      if (dlclose (h2) != 0)
+	{
+	  printf ("closing h2 failed: %s\n", dlerror ());
+	  exit (1);
+	}
+    }
+  return 0;
+}
--- libc/elf/reldep4mod1.c.jj	Tue May 22 12:05:24 2001
+++ libc/elf/reldep4mod1.c	Tue May 22 12:26:12 2001
@@ -0,0 +1,7 @@
+int foo (void);
+
+int foo (void)
+{
+  return 0;
+}
+
--- libc/elf/reldep4mod2.c.jj	Tue May 22 12:05:27 2001
+++ libc/elf/reldep4mod2.c	Tue May 22 10:57:02 2001
@@ -0,0 +1,6 @@
+extern int foo();
+
+int bar ()
+{
+  foo();
+}
--- libc/elf/reldep4mod3.c.jj	Tue May 22 12:05:24 2001
+++ libc/elf/reldep4mod3.c	Tue May 22 12:26:19 2001
@@ -0,0 +1,7 @@
+int foo (void);
+
+int foo (void)
+{
+  return 0;
+}
+
--- libc/elf/reldep4mod4.c.jj	Tue May 22 12:05:27 2001
+++ libc/elf/reldep4mod4.c	Tue May 22 10:57:02 2001
@@ -0,0 +1,6 @@
+extern int foo();
+
+int bar ()
+{
+  foo();
+}

	Jakub


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