about summary refs log tree commit diff
path: root/elf/rtld.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-01-21 06:10:42 +0000
committerUlrich Drepper <drepper@redhat.com>1997-01-21 06:10:42 +0000
commitfd26970f3324277683be531ad2c31f42e19e4b48 (patch)
tree5d9802aa7e77cc5c0f4b87ac661fe264a93bbe2e /elf/rtld.c
parentf9c53d1159ff05ac533d3351c70df1ea32c2119d (diff)
downloadglibc-fd26970f3324277683be531ad2c31f42e19e4b48.tar.gz
glibc-fd26970f3324277683be531ad2c31f42e19e4b48.tar.xz
glibc-fd26970f3324277683be531ad2c31f42e19e4b48.zip
update from main archive 970120 cvs/libc-970121
Tue Jan 21 04:05:20 1997  Ulrich Drepper  <drepper@cygnus.com>

	* version.h (VERSION): Bump to 1.101.

	Implement -d and -r option to `ldd' to check relocations.
	* elf/dl-error.c: Add another method to intercept errors.
	(_dl_receive_error): New function.  Install user defined handler.
	(receiver): New variable.  Contains pointer to user provided handler.
	(_dl_signal_error): If user provided handler is installed call this.
	* elf/dl-load.c (_dl_map_object): When shared object is not found in
	trace mode initialize a few more fields so that lookup can actually
	happen but always fails.
	* elf/ldd.sh.in: Rewrite argument handling.  Recognize new arguments
	to trigger reloation test.  Return with appropriate error code if
	a file wasn't found.  Print warning if object is not executable.
	* elf/ldd.bash.in: Likewise.
	* elf/link.h (receiver_fct): New type.  Used in _dl_receive_error.
	(_dl_sysdep_error): New prototype.
	(_dl_receive_error): New prototype.
	(_dl_signal_error): Remove  __attribute__ ((__noreturn__)).
	* elf/rtld.c (dl_main): Rewrite argument handling.  More than
	one argument allowed.  Recognize --data-relocs and --function-relocs
	arguments.
	Don't determine `lazy' mode from LD_BIND_NOW environment variable
	when in trace mode.
	If in trace mode and either --data-relocs or --function-relocs is
	given perform relocation.  Report errors using print_unresolved
	function.
	(print_unresolved): New function.  Print information about missing
	symbol on stderr.
	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_error): New function.
	Like _dl_sysdep_message but print to stderr.
	* sysdeps/mach/hurd/dl-sysdep.c: Likewise.

	* sysdeps/generic/sockaddrcom.h: Add definition of sa_family_t.
	Reported by Andreas Schwab.
	(__SOCKADDR_COMMON): Use sa_family_t for family member.
	* sysdeps/unix/bsd/bsd4.4/sockaddrcom.h: Likewise.

	Linux/Sparc support by Miguel de Icaza.
	* sysdeps/sparc/fpu_control.h: New file.
	* sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S: New file.
	* sysdeps/unix/sysv/linux/sparc/brk.c: New file.
	* sysdeps/unix/sysv/linux/sparc/profil-counter.h: New file.
	* sysdeps/unix/sysv/linux/sparc/sigaction.c: New file.
	* sysdeps/unix/sysv/linux/sparc/socket.S: New file.
	* sysdeps/unix/sysv/linux/sparc/syscall.S: New file.
	* sysdeps/unix/sysv/linux/sparc/sysdep.h: New file.
	* sysdeps/unix/sysv/linux/sparc/Dist: New file.
	* sysdeps/unix/sysv/linux/sparc/Makefile: New file.

	* sysdeps/unix/sysv/linux/net/if_arp.h: Don't use kernel header.
	Provide own definition based on 4.4BSD and Linux.
	* sysdeps/unix/sysv/linux/net/ppp_defs.h: Define __u32 before
	including <linux/ppp_defs.h>.
	* sysdeps/unix/sysv/linux/sys/msq_buf.h (struct msqid_ds): Don't
	use __pid_t since the kernel might have a different size.
	* sysdeps/unix/sysv/linux/sys/shm_buf.h (struct shmid_ds): Likewise.
	Reported by Andreas Schwab.

	* time/asctime.c: Update copyright.
	* time/dysize.c: Likewise.
	* time/gmtime.c: Likewise.
	* time/timegm.c: Likewise.
	* time/offtime.c: Likewise.  De-ANSI-declfy.

	* time/tzset.c (__tzset_internal): When TZ envvar does not name a
	DST timezone don't default to offset -1.

	* sysdeps/unix/sysv/linux/net/route.h: Don't use kernel header.
	Reported by a sun <asun@zoology.washington.edu>.

	* resolv/Makefile: Correct spelling: subdirs-dirs -> subdir-dirs.

	* sysdeps/stub/sysv_signal.c: New file.  Stub implementation.

	* Makefile (distribute): Add mcheck.h.

	* nis/Makefile (distribute): Add nss-nis.h.

	* libio/Makefile (routines): Change vdprintf to iovdprintf to prevent
	dist problem.

	* nss/Makefile (distribute): Add digits_dots.c.

	* sysdeps/unix/sysv/linux/Dist: Add kernel_sigaction.h.
	* sysdeps/unix/sysv/linux/alpha/Dist: Add sys/procfs.h.
	* sysdeps/unix/sysv/linux/sparc/Dist: Add clone.S.
	* new-malloc/Makefile (distribute): Add mcheck-init.c and mcheck.h.

Mon Jan 20 17:54:28 1997  Sven Verdoolaege  <skimo@breughel.ufsia.ac.be>

	* manual/filesys.texi: Fix little problem (reentrant->readdir).

Fri Jan 17 19:07:07 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* configure.in [$elf=yes]: Check for support of .previous and
	.popsection in the assembler.
	* config.h.in: Add HAVE_ASM_PREVIOUS_DIRECTIVE and
	HAVE_ASM_POPSECTION_DIRECTIVE.
	* libc-symbols.h (__make_section_unallocated) [HAVE_ELF]: Define
	appropriate if either .previous or .popsection is supported.
	(libc_warning) [HAVE_ELF]: Use it here.

Sat Jan 18 22:15:26 1997  Richard Henderson  <rth@tamu.edu>

	* Makeconfig (CFLAGS-.so): Add -fno-common to prevent odd sorts of
	errors that can occur when linking libc.so.

Mon Jan 20 05:20:49 1997  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-load.c (open_path): When running setuid don't try
	a directory if it is not given with the full name.

	* elf/Makefile (before-compile): New variable.  Mention trusted-dirs.h.
	(trusted-dirs.h): Construct file from $(default-rpath) and
	$(user-defined-trusted-dirs) variables.
	* elf/dl-load.c (_dl_map_object): Pass additional argument to open_path
	which is NULL except for the LD_LIBRARY_PATH pass in which case it
	is a pointer to the list of directories from the trusted-dirs.h
	file.
	(open_path): Accept additional argument with list of trusted dirs.
	When running setuid and a list of trusted dirs is given only use
	those which are mentioned in the list.

	* elf/rtld.c (dl_main): Don't reject whole LD_LIBRARY_PATH when
	running setuid.  Instead accept entries which do not contain a '/'.

	* Makeconfig: Correct comment about +(default_cflags).

Mon Jan 20 05:11:14 1997  Hrvoje Niksic  <hniksic@srce.hr>

	* time/strptime.c (recursive): Use && not || to test for valid
	argument.

Mon Jan 20 05:06:50 1997  Ulrich Drepper  <drepper@cygnus.com>

	* elf/ldd.sh.in: Exit with value 1 if an error occured.
	* elf/ldd.bash.in: Likewise.

	* elf/rtld.c (dl_main): Do not always ignore LD_PRELOAD when the
	binary runs setuid.  It is save to use those entries which do not
	contain a '/'.  This is compatible with Solaris-2.
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c124
1 files changed, 92 insertions, 32 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index 39435f8243..f9a2cd3d03 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -44,6 +44,10 @@ extern void *_dl_sysdep_read_whole_file (const char *filename,
 					 size_t *filesize_ptr,
 					 int mmap_prot);
 
+/* Helper function to handle errors while resolving symbols.  */
+static void print_unresolved (const char *errstring, const char *objname);
+
+
 int _dl_argc;
 char **_dl_argv;
 const char *_dl_rpath;
@@ -142,11 +146,19 @@ dl_main (const ElfW(Phdr) *phdr,
   enum { normal, list, verify, trace } mode;
   struct link_map **preloads;
   unsigned int npreloads;
+  const char *preloadlist;
   size_t file_size;
   char *file;
 
   mode = getenv ("LD_TRACE_LOADED_OBJECTS") != NULL ? trace : normal;
 
+  /* LAZY is determined by the parameters --datadeps and --function-deps
+     if we trace the binary.  */
+  if (mode == trace)
+    lazy = -1;
+  else
+    lazy = !__libc_enable_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
+
   /* Set up a flag which tells we are just starting.  */
   _dl_starting_up = 1;
 
@@ -186,22 +198,44 @@ of this helper program; chances are you did not intend to run this program.\n",
       /* Note the place where the dynamic linker actually came from.  */
       _dl_rtld_map.l_name = _dl_argv[0];
 
-      if (! strcmp (_dl_argv[1], "--list"))
-	{
-	  mode = list;
+      while (_dl_argc > 1)
+	if (! strcmp (_dl_argv[1], "--list"))
+	  {
+	    mode = list;
+	    lazy = -1;	/* This means do no dependency analysis.  */
 
-	  ++_dl_skip_args;
-	  --_dl_argc;
-	  ++_dl_argv;
-	}
-      else if (! strcmp (_dl_argv[1], "--verify"))
-	{
-	  mode = verify;
+	    ++_dl_skip_args;
+	    --_dl_argc;
+	    ++_dl_argv;
+	  }
+	else if (! strcmp (_dl_argv[1], "--verify"))
+	  {
+	    mode = verify;
 
-	  ++_dl_skip_args;
-	  --_dl_argc;
-	  ++_dl_argv;
-	}
+	    ++_dl_skip_args;
+	    --_dl_argc;
+	    ++_dl_argv;
+	  }
+	else if (! strcmp (_dl_argv[1], "--data-relocs"))
+	  {
+	    mode = trace;
+	    lazy = 1;	/* This means do only data relocation analysis.  */
+
+	    ++_dl_skip_args;
+	    --_dl_argc;
+	    ++_dl_argv;
+	  }
+	else if (! strcmp (_dl_argv[1], "--function-relocs"))
+	  {
+	    mode = trace;
+	    lazy = 0;	/* This means do also function relocation analysis.  */
+
+	    ++_dl_skip_args;
+	    --_dl_argc;
+	    ++_dl_argv;
+	  }
+	else
+	  break;
 
       ++_dl_skip_args;
       --_dl_argc;
@@ -311,23 +345,22 @@ of this helper program; chances are you did not intend to run this program.\n",
   preloads = NULL;
   npreloads = 0;
 
-  if (! __libc_enable_secure)
+  preloadlist = getenv ("LD_PRELOAD");
+  if (preloadlist)
     {
-      const char *preloadlist = getenv ("LD_PRELOAD");
-      if (preloadlist)
-	{
-	  /* The LD_PRELOAD environment variable gives a white space
-	     separated list of libraries that are loaded before the
-	     executable's dependencies and prepended to the global
-	     scope list.  */
-	  char *list = strdupa (preloadlist);
-	  char *p;
-	  while ((p = strsep (&list, " ")) != NULL)
-	    {
-	      (void) _dl_map_object (NULL, p, lt_library, 0);
-	      ++npreloads;
-	    }
-	}
+      /* The LD_PRELOAD environment variable gives a white space
+	 separated list of libraries that are loaded before the
+	 executable's dependencies and prepended to the global scope
+	 list.  If the binary is running setuid all elements
+	 containing a '/' are ignored since it is insecure.  */
+      char *list = strdupa (preloadlist);
+      char *p;
+      while ((p = strsep (&list, " ")) != NULL)
+	if (! __libc_enable_secure || strchr (p, '/') == NULL)
+	  {
+	    (void) _dl_map_object (NULL, p, lt_library, 0);
+	    ++npreloads;
+	  }
     }
 
   /* Read the contents of the file.  */
@@ -496,12 +529,31 @@ of this helper program; chances are you did not intend to run this program.\n",
 	      *--bp = '0';
 	    _dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
 	  }
+      else if (lazy >= 0)
+	{
+	  /* We have to do symbol dependency testing.  */
+	  void doit (void)
+	    {
+	      _dl_relocate_object (l, _dl_object_relocation_scope (l), lazy);
+	    }
+
+	  l = _dl_loaded;
+	  while (l->l_next)
+	    l = l->l_next;
+	  do
+	    {
+	      if (l != &_dl_rtld_map && l->l_opencount > 0)
+		{
+		  _dl_receive_error (print_unresolved, doit);
+		  *_dl_global_scope_end = NULL;
+		}
+	      l = l->l_prev;
+	    } while (l);
+	}
 
       _exit (0);
     }
 
-  lazy = !__libc_enable_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
-
   {
     /* Now we have all the objects loaded.  Relocate them all except for
        the dynamic linker itself.  We do this in reverse order so that copy
@@ -573,3 +625,11 @@ of this helper program; chances are you did not intend to run this program.\n",
   /* Once we return, _dl_sysdep_start will invoke
      the DT_INIT functions and then *USER_ENTRY.  */
 }
+
+/* This is a little helper function for resolving symbols while
+   tracing the binary.  */
+static void
+print_unresolved (const char *errstring, const char *objname)
+{
+  _dl_sysdep_error (errstring, "	(", objname, ")\n", NULL);
+}