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] Restore dlsym(RTLD_NEXT, ...) behaviour (take 2)


On Thu, May 10, 2001 at 10:01:38AM -0700, Ulrich Drepper wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > But as I've tried to explain in the test, RTLD_DEFAULT gives a different
> > answer than RTLD_NEXT would even for the main program.
> 
> This is the test case I would have accepted:

Ok, here are two variants of the patch.
The first one requires more code (though within not-__builtin_expected if)
and will catch and report attempts to call dlsym(RTLD_NEXT, ) even from
places above main program not belonging to DSOs, the second one will only
report those for statically linked binaries or if caller is below start of
main program (otherwise if the caller does not belong to a particular DSO it
will assume it is from main program). Pick the one you like more.
Note that dlsym(RTLD_DEFAULT, ) will segfault in static programs anyway,
so it is questionable how good the RTLD_NEXT error reporting has to be.
Both patches include the testcase, which passed make check.

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

	* elf/dl-sym.c (_dl_sym, _dl_vsym): Only signal error if not called
	from the main program.
	* elf/dl-error.c (_dl_signal_error): Change NULL objname into "".
	* elf/restest2.c: New test.
	* elf/Makefile (tests): Add restest2.
	(restest2, LDFLAGS-restest2): Add.

--- libc/elf/dl-sym.c.jj	Thu Nov  2 08:50:59 2000
+++ libc/elf/dl-sym.c	Fri May 11 01:06:13 2001
@@ -1,5 +1,5 @@
 /* Look up a symbol in a shared object loaded by `dlopen'.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -65,8 +65,22 @@ _dl_sym (void *handle, const char *name,
       else
 	{
 	  if (__builtin_expect (match == _dl_loaded, 0))
-	    _dl_signal_error (0, NULL, N_("\
+	    {
+	      if (! _dl_loaded
+		  || _dl_loaded->l_addr != 0
+		  || caller < _dl_loaded->l_map_start)
+		l = handle;
+	      else
+		/* See if caller is below first DSO above main program.  */
+		for (l = _dl_loaded->l_next; l != NULL; l = l->l_next)
+		  if (l->l_addr != 0 && caller >= l->l_map_start
+		      && l->l_map_start > _dl_loaded->l_map_start)
+		    break;
+
+	      if (l != NULL)
+	        _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
+	    }
 
 	  l = match;
 	  while (l->l_loader != NULL)
@@ -121,9 +135,23 @@ _dl_vsym (void *handle, const char *name
 					  &vers, 0, 0);
   else if (handle == RTLD_NEXT)
     {
-      if (match == _dl_loaded)
-	_dl_signal_error (0, NULL, N_("\
+      if (__builtin_expect (match == _dl_loaded, 0))
+	{
+	  if (! _dl_loaded
+	      || _dl_loaded->l_addr != 0
+	      || caller < _dl_loaded->l_map_start)
+	    l = handle;
+	  else
+	    /* See if caller is below first DSO above main program.  */
+	    for (l = _dl_loaded->l_next; l != NULL; l = l->l_next)
+	      if (l->l_addr != 0 && caller >= l->l_map_start
+		  && l->l_map_start > _dl_loaded->l_map_start)
+		break;
+
+	  if (l != NULL)
+	    _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
+	}
 
       l = match;
       while (l->l_loader != NULL)
--- libc/elf/dl-error.c.jj	Fri Mar  2 13:44:29 2001
+++ libc/elf/dl-error.c	Thu May 10 15:58:08 2001
@@ -71,6 +71,8 @@ _dl_signal_error (int errcode, const cha
     errstring = N_("DYNAMIC LINKER BUG!!!");
 
   lcatch = tsd_getspecific ();
+  if (objname == NULL)
+    objname = "";
   if (lcatch != NULL)
     {
       /* We are inside _dl_catch_error.  Return to it.  We have to
@@ -100,7 +102,7 @@ _dl_signal_error (int errcode, const cha
       _dl_fatal_printf ("\
 %s: error while loading shared libraries: %s%s%s%s%s\n",
 			_dl_argv[0] ?: "<program name unknown>",
-			objname ?: "", objname && *objname ? ": " : "",
+			objname, *objname ? ": " : "",
 			errstring, errcode ? ": " : "",
 			(errcode
 			 ? __strerror_r (errcode, buffer, sizeof buffer)
--- libc/elf/restest2.c.jj	Fri May 11 00:43:36 2001
+++ libc/elf/restest2.c	Fri May 11 01:32:26 2001
@@ -0,0 +1,33 @@
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <error.h>
+#include <mcheck.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+pid_t pid, pid2;
+
+pid_t getpid(void)
+{
+  pid_t (*f)(void);
+  f = (pid_t (*)(void)) dlsym (RTLD_NEXT, "getpid");
+  if (f == NULL)
+    error (EXIT_FAILURE, 0, "dlsym (RTLD_NEXT, \"getpid\"): %s", dlerror ());
+  return (pid2 = f()) + 26;
+}
+
+int
+main (void)
+{
+  pid_t (*f)(void);
+
+  mtrace ();
+
+  f = (pid_t (*)(void)) dlsym (RTLD_DEFAULT, "getpid");
+  if (f == NULL)
+    error (EXIT_FAILURE, 0, "dlsym (RTLD_DEFAULT, \"getpid\"): %s", dlerror ());
+  pid = f();
+  if (pid != pid2 + 26)
+    error (EXIT_FAILURE, 0, "main getpid() not called");
+  return 0;
+}
--- libc/elf/Makefile.jj	Tue Apr 17 23:58:34 2001
+++ libc/elf/Makefile	Fri May 11 00:47:48 2001
@@ -101,7 +101,8 @@ tests = loadtest restest1 preloadtest lo
 	constload1 order $(tests-vis-$(have-protected)) noload filter unload \
 	reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
 	$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
-	neededtest3 neededtest4 unload2 lateglobal initfirst global
+	neededtest3 neededtest4 unload2 lateglobal initfirst global \
+	restest2
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
 tests-nodelete-yes = nodelete
@@ -302,6 +303,9 @@ $(objpfx)neededtest4.out: $(objpfx)neede
 
 $(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl)
 LDFLAGS-restest1 = -rdynamic
+
+$(objpfx)restest2: $(libdl)
+LDFLAGS-restest2 = -rdynamic
 
 $(objpfx)restest1.out: $(test-modules)
 
2001-05-11  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-sym.c (_dl_sym, _dl_vsym): Only signal error if not called
	from the main program.
	* elf/dl-error.c (_dl_signal_error): Change NULL objname into "".
	* elf/restest2.c: New test.
	* elf/Makefile (tests): Add restest2.
	(restest2, LDFLAGS-restest2): Add.

--- libc/elf/dl-sym.c.jj	Thu Nov  2 08:50:59 2000
+++ libc/elf/dl-sym.c	Fri May 11 01:06:13 2001
@@ -1,5 +1,5 @@
 /* Look up a symbol in a shared object loaded by `dlopen'.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -65,8 +65,13 @@ _dl_sym (void *handle, const char *name,
       else
 	{
 	  if (__builtin_expect (match == _dl_loaded, 0))
-	    _dl_signal_error (0, NULL, N_("\
+	    {
+	      if (! _dl_loaded
+		  || _dl_loaded->l_addr != 0
+		  || caller < _dl_loaded->l_map_start)
+	        _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
+	    }
 
 	  l = match;
 	  while (l->l_loader != NULL)
@@ -121,9 +126,14 @@ _dl_vsym (void *handle, const char *name
 					  &vers, 0, 0);
   else if (handle == RTLD_NEXT)
     {
-      if (match == _dl_loaded)
-	_dl_signal_error (0, NULL, N_("\
+      if (__builtin_expect (match == _dl_loaded, 0))
+	{
+	  if (! _dl_loaded
+	      || _dl_loaded->l_addr != 0
+	      || caller < _dl_loaded->l_map_start)
+	    _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
+	}
 
       l = match;
       while (l->l_loader != NULL)
--- libc/elf/dl-error.c.jj	Fri Mar  2 13:44:29 2001
+++ libc/elf/dl-error.c	Thu May 10 15:58:08 2001
@@ -71,6 +71,8 @@ _dl_signal_error (int errcode, const cha
     errstring = N_("DYNAMIC LINKER BUG!!!");
 
   lcatch = tsd_getspecific ();
+  if (objname == NULL)
+    objname = "";
   if (lcatch != NULL)
     {
       /* We are inside _dl_catch_error.  Return to it.  We have to
@@ -100,7 +102,7 @@ _dl_signal_error (int errcode, const cha
       _dl_fatal_printf ("\
 %s: error while loading shared libraries: %s%s%s%s%s\n",
 			_dl_argv[0] ?: "<program name unknown>",
-			objname ?: "", objname && *objname ? ": " : "",
+			objname, *objname ? ": " : "",
 			errstring, errcode ? ": " : "",
 			(errcode
 			 ? __strerror_r (errcode, buffer, sizeof buffer)
--- libc/elf/restest2.c.jj	Fri May 11 00:43:36 2001
+++ libc/elf/restest2.c	Fri May 11 01:32:26 2001
@@ -0,0 +1,33 @@
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <error.h>
+#include <mcheck.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+pid_t pid, pid2;
+
+pid_t getpid(void)
+{
+  pid_t (*f)(void);
+  f = (pid_t (*)(void)) dlsym (RTLD_NEXT, "getpid");
+  if (f == NULL)
+    error (EXIT_FAILURE, 0, "dlsym (RTLD_NEXT, \"getpid\"): %s", dlerror ());
+  return (pid2 = f()) + 26;
+}
+
+int
+main (void)
+{
+  pid_t (*f)(void);
+
+  mtrace ();
+
+  f = (pid_t (*)(void)) dlsym (RTLD_DEFAULT, "getpid");
+  if (f == NULL)
+    error (EXIT_FAILURE, 0, "dlsym (RTLD_DEFAULT, \"getpid\"): %s", dlerror ());
+  pid = f();
+  if (pid != pid2 + 26)
+    error (EXIT_FAILURE, 0, "main getpid() not called");
+  return 0;
+}
--- libc/elf/Makefile.jj	Tue Apr 17 23:58:34 2001
+++ libc/elf/Makefile	Fri May 11 00:47:48 2001
@@ -101,7 +101,8 @@ tests = loadtest restest1 preloadtest lo
 	constload1 order $(tests-vis-$(have-protected)) noload filter unload \
 	reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
 	$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
-	neededtest3 neededtest4 unload2 lateglobal initfirst global
+	neededtest3 neededtest4 unload2 lateglobal initfirst global \
+	restest2
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
 tests-nodelete-yes = nodelete
@@ -302,6 +303,9 @@ $(objpfx)neededtest4.out: $(objpfx)neede
 
 $(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl)
 LDFLAGS-restest1 = -rdynamic
+
+$(objpfx)restest2: $(libdl)
+LDFLAGS-restest2 = -rdynamic
 
 $(objpfx)restest1.out: $(test-modules)
 

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