diff options
author | Ulrich Drepper <drepper@redhat.com> | 1997-01-21 06:10:42 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1997-01-21 06:10:42 +0000 |
commit | fd26970f3324277683be531ad2c31f42e19e4b48 (patch) | |
tree | 5d9802aa7e77cc5c0f4b87ac661fe264a93bbe2e /elf/dl-load.c | |
parent | f9c53d1159ff05ac533d3351c70df1ea32c2119d (diff) | |
download | glibc-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/dl-load.c')
-rw-r--r-- | elf/dl-load.c | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c index 7dc6d91a02..6a3d919976 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1,5 +1,5 @@ /* _dl_map_object -- Map in a shared object's segments from the file. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 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 @@ -409,7 +409,8 @@ _dl_map_object_from_fd (char *name, int fd, char *realname, static int open_path (const char *name, size_t namelen, const char *dirpath, - char **realname) + char **realname, + const char *trusted_dirs[]) { char *buf; const char *p; @@ -426,13 +427,42 @@ open_path (const char *name, size_t namelen, do { size_t buflen; + size_t this_len; dirpath = p; p = strpbrk (dirpath, ":;"); if (p == NULL) p = strchr (dirpath, '\0'); - if (p == dirpath) + this_len = p - dirpath; + + /* When we run a setuid program we do not accept any directory. */ + if (__libc_enable_secure) + { + /* All trusted directory must be complete name. */ + if (dirpath[0] != '/') + continue; + + /* If we got a list of trusted directories only accept one + of these. */ + if (trusted_dirs != NULL) + { + const char **trust = trusted_dirs; + + while (*trust != NULL) + if (memcmp (dirpath, *trust, this_len) == 0 + && (*trust)[this_len] == '\0') + break; + else + ++trust; + + /* If directory is not trusted, ignore this directory. */ + if (*trust == NULL) + continue; + } + } + + if (this_len == 0) { /* Two adjacent colons, or a colon at the beginning or the end of the path means to search the current directory. */ @@ -442,10 +472,10 @@ open_path (const char *name, size_t namelen, else { /* Construct the pathname to try. */ - (void) memcpy (buf, dirpath, p - dirpath); - buf[p - dirpath] = '/'; - (void) memcpy (&buf[(p - dirpath) + 1], name, namelen); - buflen = p - dirpath + 1 + namelen; + (void) memcpy (buf, dirpath, this_len); + buf[this_len] = '/'; + (void) memcpy (&buf[this_len + 1], name, namelen); + buflen = this_len + 1 + namelen; } fd = __open (buf, O_RDONLY); @@ -508,9 +538,9 @@ _dl_map_object (struct link_map *loader, const char *name, int type, size_t namelen = strlen (name) + 1; - inline void trypath (const char *dirpath) + inline void trypath (const char *dirpath, const char *trusted[]) { - fd = open_path (name, namelen, dirpath, &realname); + fd = open_path (name, namelen, dirpath, &realname, trusted); } fd = -1; @@ -521,16 +551,24 @@ _dl_map_object (struct link_map *loader, const char *name, int type, if (l && l->l_info[DT_RPATH]) trypath ((const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr + - l->l_info[DT_RPATH]->d_un.d_val)); + l->l_info[DT_RPATH]->d_un.d_val), NULL); /* If dynamically linked, try the DT_RPATH of the executable itself. */ l = _dl_loaded; if (fd == -1 && l && l->l_type != lt_loaded && l->l_info[DT_RPATH]) trypath ((const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr + - l->l_info[DT_RPATH]->d_un.d_val)); + l->l_info[DT_RPATH]->d_un.d_val), NULL); /* Try an environment variable (unless setuid). */ if (fd == -1 && ! __libc_enable_secure) - trypath (getenv ("LD_LIBRARY_PATH")); + { + static const char *trusted_dirs[] = + { +#include "trusted-dirs.h" + NULL + }; + + trypath (getenv ("LD_LIBRARY_PATH"), trusted_dirs); + } if (fd == -1) { /* Check the list of libraries in the file /etc/ld.so.cache, @@ -555,7 +593,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type, if (fd == -1) { extern const char *_dl_rpath; /* Set in rtld.c. */ - trypath (_dl_rpath); + trypath (_dl_rpath, NULL); } } else @@ -590,6 +628,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type, are only interested in the list of libraries this isn't so severe. Fake an entry with all the information we have (in fact only the name). */ + static const ElfW(Symndx) dummy_bucket = STN_UNDEF; /* Enter the new object in the list of loaded objects. */ if ((name_copy = local_strdup (name)) == NULL @@ -599,6 +638,11 @@ _dl_map_object (struct link_map *loader, const char *name, int type, /* We use an opencount of 0 as a sign for the faked entry. */ l->l_opencount = 0; l->l_reserved = 0; + l->l_buckets = &dummy_bucket; + l->l_nbuckets = 1; + l->l_relocated = 1; + + return l; } else _dl_signal_error (errno, name, "cannot open shared object file"); |