diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2013-03-20 21:50:00 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2013-03-20 21:50:00 +0000 |
commit | 9908e967b5ddb41570e5863703c45ffb3fbab784 (patch) | |
tree | adbd217af63153653339d5e162ec9e46ca3fc859 /libexec | |
parent | 105cb62bdd35500a8491e586d2e7d4cb46729185 (diff) |
- Parse colon separated paths into NULL terminated arrays of string
pointers to prepare for adding rpath ORIGIN support.
okay matthew@ millert@
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/Makefile | 4 | ||||
-rw-r--r-- | libexec/ld.so/ldconfig/Makefile | 4 | ||||
-rw-r--r-- | libexec/ld.so/ldconfig/ldconfig.8 | 4 | ||||
-rw-r--r-- | libexec/ld.so/ldconfig/library.c | 78 | ||||
-rw-r--r-- | libexec/ld.so/ldconfig/prebind.c | 7 | ||||
-rw-r--r-- | libexec/ld.so/ldconfig/prebind_path.c | 38 | ||||
-rw-r--r-- | libexec/ld.so/ldconfig/sod.c | 7 | ||||
-rw-r--r-- | libexec/ld.so/library_subr.c | 71 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 11 | ||||
-rw-r--r-- | libexec/ld.so/path.c | 98 | ||||
-rw-r--r-- | libexec/ld.so/path.h | 25 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 8 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 9 | ||||
-rw-r--r-- | libexec/ld.so/sod.c | 7 | ||||
-rw-r--r-- | libexec/ld.so/sod.h | 4 |
15 files changed, 242 insertions, 133 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile index 3fdb7016953..69eb5c23c71 100644 --- a/libexec/ld.so/Makefile +++ b/libexec/ld.so/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.41 2013/02/17 22:06:31 deraadt Exp $ +# $OpenBSD: Makefile,v 1.42 2013/03/20 21:49:59 kurt Exp $ SUBDIR=ldconfig ldd MAN= ld.so.1 @@ -14,7 +14,7 @@ PROG= ld.so VPATH=${.CURDIR}/../../lib/libc/string -SRCS= ldasm.S loader.c resolve.c dlfcn.c dl_printf.c rtld_machine.c +SRCS= ldasm.S loader.c resolve.c dlfcn.c dl_printf.c rtld_machine.c path.c SRCS+= util.c sod.c strsep.c strtol.c dir.c library_subr.c dl_prebind.c .if (${MACHINE_ARCH} == "i386") SRCS+= library_mquery.c diff --git a/libexec/ld.so/ldconfig/Makefile b/libexec/ld.so/ldconfig/Makefile index 7709d8ac85a..8f46c1d5d1e 100644 --- a/libexec/ld.so/ldconfig/Makefile +++ b/libexec/ld.so/ldconfig/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.8 2013/02/17 22:06:31 deraadt Exp $ +# $OpenBSD: Makefile,v 1.9 2013/03/20 21:49:59 kurt Exp $ # $NetBSD: Makefile,v 1.10 1995/03/06 04:24:41 cgd Exp $ MAN= ldconfig.8 @@ -8,7 +8,7 @@ MAN= ldconfig.8 .if (${ELF_TOOLCHAIN:L} == "yes") PROG= ldconfig -SRCS= ldconfig.c shlib.c etc.c prebind_delete.c debug.c prebind.c library.c sod.c +SRCS= ldconfig.c shlib.c etc.c prebind_delete.c debug.c prebind.c library.c sod.c prebind_path.c LDDIR?= $(.CURDIR)/.. #CFLAGS+=-Werror CFLAGS+=-I$(.CURDIR) -I$(.CURDIR)/.. diff --git a/libexec/ld.so/ldconfig/ldconfig.8 b/libexec/ld.so/ldconfig/ldconfig.8 index c4d00579bac..08549e6a6d3 100644 --- a/libexec/ld.so/ldconfig/ldconfig.8 +++ b/libexec/ld.so/ldconfig/ldconfig.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ldconfig.8,v 1.25 2007/05/31 19:19:39 jmc Exp $ +.\" $OpenBSD: ldconfig.8,v 1.26 2013/03/20 21:49:59 kurt Exp $ .\" .\" Copyright (c) 1993,1995 Paul Kranenburg .\" All rights reserved. @@ -29,7 +29,7 @@ .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: March 20 2013 $ .Dt LDCONFIG 8 .Os .Sh NAME diff --git a/libexec/ld.so/ldconfig/library.c b/libexec/ld.so/ldconfig/library.c index 07b5a70d505..f5de94257c3 100644 --- a/libexec/ld.so/ldconfig/library.c +++ b/libexec/ld.so/ldconfig/library.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library.c,v 1.3 2009/12/30 04:30:01 drahn Exp $ */ +/* $OpenBSD: library.c,v 1.4 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 2006 Dale Rahn <drahn@dalerahn.com> * @@ -34,12 +34,11 @@ #include "prebind.h" #include "prebind_struct.h" -/* TODO - library path from ldconfig */ -#define DEFAULT_PATH "/usr/lib" +char * _dl_default_path[2] = { "/usr/lib", NULL }; elf_object_t * elf_load_shlib_hint(struct sod *sod, struct sod *req_sod, - int ignore_hints, const char *libpath); -char * elf_find_shlib(struct sod *sodp, const char *searchpath, int nohints); + int ignore_hints, char **libpath); +char * elf_find_shlib(struct sod *sodp, char **searchpath, int nohints); elf_object_t * elf_tryload_shlib(const char *libname); int elf_match_file(struct sod *sodp, char *name, int namelen); @@ -56,6 +55,7 @@ load_lib(const char *name, struct elf_object *parent) ignore_hints = 0; if(strchr(name, '/')) { + char *paths[2]; char *lpath, *lname; lpath = strdup(name); @@ -70,10 +70,12 @@ load_lib(const char *name, struct elf_object *parent) _dl_build_sod(lname, &sod); req_sod = sod; + paths[0] = lpath; + paths[1] = NULL; /* this code does not allow lower minors */ fullpathagain: object = elf_load_shlib_hint(&sod, &req_sod, - ignore_hints, lpath); + ignore_hints, paths); if (object != NULL) goto fullpathdone; @@ -95,15 +97,15 @@ fullpathdone: /* ignore LD_LIBRARY_PATH */ again: - if (parent->dyn.rpath != NULL) { + if (parent->rpath != NULL) { object = elf_load_shlib_hint(&sod, &req_sod, - ignore_hints, parent->dyn.rpath); + ignore_hints, parent->rpath); if (object != NULL) goto done; } - if (parent != load_object && load_object->dyn.rpath != NULL) { + if (parent != load_object && load_object->rpath != NULL) { object = elf_load_shlib_hint(&sod, &req_sod, - ignore_hints, load_object->dyn.rpath); + ignore_hints, load_object->rpath); if (object != NULL) goto done; } @@ -130,7 +132,7 @@ done: */ elf_object_t * elf_load_shlib_hint(struct sod *sod, struct sod *req_sod, - int ignore_hints, const char *libpath) + int ignore_hints, char **libpath) { elf_object_t *object = NULL; char *hint; @@ -151,12 +153,11 @@ elf_load_shlib_hint(struct sod *sod, struct sod *req_sod, char elf_hint_store[MAXPATHLEN]; char * -elf_find_shlib(struct sod *sodp, const char *searchpath, int nohints) +elf_find_shlib(struct sod *sodp, char **searchpath, int nohints) { - char *hint, lp[PATH_MAX + 10], *path; + char *hint, **pp; struct sod tsod, bsod; /* transient and best sod */ struct dirent *dp; - const char *pp; int match, len; DIR *dd; @@ -177,29 +178,11 @@ elf_find_shlib(struct sod *sodp, const char *searchpath, int nohints) /* search hints requesting matches for only * the searchpath directories, */ - pp = searchpath; - while (pp) { - path = lp; - while (path < lp + PATH_MAX && - *pp && *pp != ':' && *pp != ';') - *path++ = *pp++; - *path = 0; - - /* interpret "" as curdir "." */ - if (lp[0] == '\0') { - lp[0] = '.'; - lp[1] = '\0'; - } - + for (pp = searchpath; *pp != NULL; pp++) { hint = _dl_findhint((char *)sodp->sod_name, - sodp->sod_major, sodp->sod_minor, lp); + sodp->sod_major, sodp->sod_minor, *pp); if (hint != NULL) return hint; - - if (*pp) /* Try curdir if ':' at end */ - pp++; - else - pp = 0; } } @@ -213,22 +196,10 @@ nohints: if (_dl_hint_search_path != NULL) searchpath = _dl_hint_search_path; else - searchpath = DEFAULT_PATH; + searchpath = _dl_default_path; } - pp = searchpath; - while (pp) { - path = lp; - while (path < lp + PATH_MAX && *pp && *pp != ':' && *pp != ';') - *path++ = *pp++; - *path = 0; - - /* interpret "" as curdir "." */ - if (lp[0] == '\0') { - lp[0] = '.'; - lp[1] = '\0'; - } - - if ((dd = opendir(lp)) != NULL) { + for (pp = searchpath; *pp != NULL; pp++) { + if ((dd = opendir(*pp)) != NULL) { match = 0; while ((dp = readdir(dd)) != NULL) { tsod = *sodp; @@ -250,9 +221,9 @@ nohints: bsod = tsod; match = 1; len = strlcpy( - elf_hint_store, lp, + elf_hint_store, *pp, MAXPATHLEN); - if (lp[len-1] != '/') { + if (pp[0][len-1] != '/') { elf_hint_store[len] = '/'; len++; @@ -272,11 +243,6 @@ nohints: return (elf_hint_store); } } - - if (*pp) /* Try curdir if ':' at end */ - pp++; - else - pp = 0; } return NULL; } diff --git a/libexec/ld.so/ldconfig/prebind.c b/libexec/ld.so/ldconfig/prebind.c index e8890184343..f908e45680c 100644 --- a/libexec/ld.so/ldconfig/prebind.c +++ b/libexec/ld.so/ldconfig/prebind.c @@ -1,4 +1,4 @@ -/* $OpenBSD: prebind.c,v 1.18 2013/01/23 19:15:58 miod Exp $ */ +/* $OpenBSD: prebind.c,v 1.19 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 2006 Dale Rahn <drahn@dalerahn.com> * @@ -32,6 +32,7 @@ #include <err.h> #include "resolve.h" #include "link.h" +#include "path.h" #include "sod.h" #ifndef __mips64__ #include "machine/reloc.h" @@ -671,8 +672,8 @@ elf_load_object(void *pexe, const char *name) object->dyn.jmprel = 0; } if (object->dyn.rpath != NULL){ - object->dyn.rpath = strdup(object->dyn.rpath); - if (object->dyn.rpath == NULL) { + object->rpath = _dl_split_path(object->dyn.rpath); + if (object->rpath == NULL) { printf("unable to allocate rpath for %s\n", name); exit(10); diff --git a/libexec/ld.so/ldconfig/prebind_path.c b/libexec/ld.so/ldconfig/prebind_path.c new file mode 100644 index 00000000000..eab54011535 --- /dev/null +++ b/libexec/ld.so/ldconfig/prebind_path.c @@ -0,0 +1,38 @@ +/* $OpenBSD: prebind_path.c,v 1.1 2013/03/20 21:49:59 kurt Exp $ */ + +/* + * Copyright (c) 2013 Kurt Miller <kurt@intricatesoftware.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> + +void * +_dl_malloc(size_t need) +{ + void *ret = malloc(need); + if (ret != NULL) + memset(ret, 0, need); + return (ret); +} + +void +_dl_free(void *p) +{ + free(p); +} + +#include "path.c" diff --git a/libexec/ld.so/ldconfig/sod.c b/libexec/ld.so/ldconfig/sod.c index d3383ee7b14..b24fb565a3e 100644 --- a/libexec/ld.so/ldconfig/sod.c +++ b/libexec/ld.so/ldconfig/sod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sod.c,v 1.1 2006/05/12 23:20:53 deraadt Exp $ */ +/* $OpenBSD: sod.c,v 1.2 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 1993 Paul Kranenburg @@ -50,6 +50,7 @@ #include "archdep.h" #include "util.h" #endif +#include "path.h" #include "sod.h" int _dl_hinthash(char *cp, int vmajor, int vminor); @@ -138,7 +139,7 @@ backout: static struct hints_header *hheader = NULL; static struct hints_bucket *hbuckets; static char *hstrtab; -char *_dl_hint_search_path = NULL; +char **_dl_hint_search_path = NULL; #define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1) @@ -173,7 +174,7 @@ _dl_maphints(void) hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab); hstrtab = (char *)(addr + hheader->hh_strtab); if (hheader->hh_version >= LD_HINTS_VERSION_2) - _dl_hint_search_path = hstrtab + hheader->hh_dirlist; + _dl_hint_search_path = _dl_split_path(hstrtab + hheader->hh_dirlist); /* close the file descriptor, leaving the hints mapped */ close(hfd); diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c index 62beabcedd0..da6dbe80fa7 100644 --- a/libexec/ld.so/library_subr.c +++ b/libexec/ld.so/library_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_subr.c,v 1.36 2012/03/21 04:28:45 matthew Exp $ */ +/* $OpenBSD: library_subr.c,v 1.37 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -41,7 +41,7 @@ #include "dir.h" #include "sod.h" -#define DEFAULT_PATH "/usr/lib" +char * _dl_default_path[2] = { "/usr/lib", NULL }; /* STATIC DATA */ @@ -125,11 +125,10 @@ _dl_cmp_sod(struct sod *sodp, const struct sod *lsod) char _dl_hint_store[MAXPATHLEN]; char * -_dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints) +_dl_find_shlib(struct sod *sodp, char **searchpath, int nohints) { - char *hint, lp[PATH_MAX + 10], *path; + char *hint, **pp; struct dirent *dp; - const char *pp; int match, len; _dl_DIR *dd; struct sod tsod, bsod; /* transient and best sod */ @@ -151,29 +150,11 @@ _dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints) /* search hints requesting matches for only * the searchpath directories, */ - pp = searchpath; - while (pp) { - path = lp; - while (path < lp + PATH_MAX && - *pp && *pp != ':' && *pp != ';') - *path++ = *pp++; - *path = 0; - - /* interpret "" as curdir "." */ - if (lp[0] == '\0') { - lp[0] = '.'; - lp[1] = '\0'; - } - + for (pp = searchpath; *pp != NULL; pp++) { hint = _dl_findhint((char *)sodp->sod_name, - sodp->sod_major, sodp->sod_minor, lp); + sodp->sod_major, sodp->sod_minor, *pp); if (hint != NULL) return hint; - - if (*pp) /* Try curdir if ':' at end */ - pp++; - else - pp = 0; } } @@ -187,23 +168,11 @@ nohints: if (_dl_hint_search_path != NULL) searchpath = _dl_hint_search_path; else - searchpath = DEFAULT_PATH; + searchpath = _dl_default_path; } _dl_memset(&bsod, 0, sizeof(bsod)); - pp = searchpath; - while (pp) { - path = lp; - while (path < lp + PATH_MAX && *pp && *pp != ':' && *pp != ';') - *path++ = *pp++; - *path = 0; - - /* interpret "" as curdir "." */ - if (lp[0] == '\0') { - lp[0] = '.'; - lp[1] = '\0'; - } - - if ((dd = _dl_opendir(lp)) != NULL) { + for (pp = searchpath; *pp != NULL; pp++) { + if ((dd = _dl_opendir(*pp)) != NULL) { match = 0; while ((dp = _dl_readdir(dd)) != NULL) { tsod = *sodp; @@ -225,9 +194,9 @@ nohints: bsod = tsod; match = 1; len = _dl_strlcpy( - _dl_hint_store, lp, + _dl_hint_store, *pp, MAXPATHLEN); - if (lp[len-1] != '/') { + if (pp[0][len-1] != '/') { _dl_hint_store[len] = '/'; len++; @@ -247,11 +216,6 @@ nohints: return (_dl_hint_store); } } - - if (*pp) /* Try curdir if ':' at end */ - pp++; - else - pp = 0; } return NULL; } @@ -351,6 +315,7 @@ _dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags) ignore_hints = 0; if (_dl_strchr(libname, '/')) { + char *paths[2]; char *lpath, *lname; lpath = _dl_strdup(libname); lname = _dl_strrchr(lpath, '/'); @@ -370,8 +335,10 @@ _dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags) _dl_build_sod(lname, &sod); req_sod = sod; + paths[0] = lpath; + paths[1] = NULL; fullpathagain: - hint = _dl_find_shlib(&req_sod, lpath, ignore_hints); + hint = _dl_find_shlib(&req_sod, paths, ignore_hints); if (hint != NULL) goto fullpathdone; @@ -405,15 +372,15 @@ again: } /* Check DT_RPATH. */ - if (parent->dyn.rpath != NULL) { - hint = _dl_find_shlib(&req_sod, parent->dyn.rpath, ignore_hints); + if (parent->rpath != NULL) { + hint = _dl_find_shlib(&req_sod, parent->rpath, ignore_hints); if (hint != NULL) goto done; } /* Check main program's DT_RPATH, if parent != main program */ - if (parent != _dl_objects && _dl_objects->dyn.rpath != NULL) { - hint = _dl_find_shlib(&req_sod, _dl_objects->dyn.rpath, ignore_hints); + if (parent != _dl_objects && _dl_objects->rpath != NULL) { + hint = _dl_find_shlib(&req_sod, _dl_objects->rpath, ignore_hints); if (hint != NULL) goto done; } diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index de24e6e83fc..8e6ac3ce016 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.130 2013/01/11 21:17:07 miod Exp $ */ +/* $OpenBSD: loader.c,v 1.131 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -40,6 +40,7 @@ #include "syscall.h" #include "archdep.h" +#include "path.h" #include "resolve.h" #include "sod.h" #include "stdlib.h" @@ -63,7 +64,8 @@ void _dl_call_init_recurse(elf_object_t *object, int initfirst); const char *_dl_progname; int _dl_pagesz; -char *_dl_libpath; +char **_dl_libpath; + char *_dl_preload; char *_dl_bindnow; char *_dl_traceld; @@ -212,14 +214,14 @@ _dl_setup_env(char **envp) /* * Get paths to various things we are going to use. */ - _dl_libpath = _dl_getenv("LD_LIBRARY_PATH", envp); + _dl_debug = _dl_getenv("LD_DEBUG", envp); + _dl_libpath = _dl_split_path(_dl_getenv("LD_LIBRARY_PATH", envp)); _dl_preload = _dl_getenv("LD_PRELOAD", envp); _dl_bindnow = _dl_getenv("LD_BIND_NOW", envp); _dl_traceld = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp); _dl_tracefmt1 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT1", envp); _dl_tracefmt2 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT2", envp); _dl_traceprog = _dl_getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", envp); - _dl_debug = _dl_getenv("LD_DEBUG", envp); _dl_norandom = _dl_getenv("LD_NORANDOM", envp); _dl_noprebind = _dl_getenv("LD_NOPREBIND", envp); _dl_prebind_validate = _dl_getenv("LD_PREBINDVALIDATE", envp); @@ -230,6 +232,7 @@ _dl_setup_env(char **envp) */ if (_dl_issetugid()) { /* Zap paths if s[ug]id... */ if (_dl_libpath) { + _dl_free_path(_dl_libpath); _dl_libpath = NULL; _dl_unsetenv("LD_LIBRARY_PATH", envp); } diff --git a/libexec/ld.so/path.c b/libexec/ld.so/path.c new file mode 100644 index 00000000000..5cc98ae25bc --- /dev/null +++ b/libexec/ld.so/path.c @@ -0,0 +1,98 @@ +/* $OpenBSD: path.c,v 1.1 2013/03/20 21:49:59 kurt Exp $ */ + +/* + * Copyright (c) 2013 Kurt Miller <kurt@intricatesoftware.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include "path.h" +#include "util.h" + +char ** +_dl_split_path(const char *searchpath) +{ + int pos = 0; + int count = 1; + const char *pp, *p_begin; + char **retval; + + if (searchpath == NULL) + return (NULL); + + /* Count ':' or ';' in searchpath */ + pp = searchpath; + while (*pp) { + if (*pp == ':' || *pp == ';') + count++; + pp++; + } + + /* one more for NULL entry */ + count++; + + retval = _dl_malloc(count * sizeof(retval)); + + if (retval == NULL) + return (NULL); + + pp = searchpath; + while (pp) { + p_begin = pp; + while (*pp != '\0' && *pp != ':' && *pp != ';') + pp++; + + /* interpret "" as curdir "." */ + if (p_begin == pp) { + retval[pos] = _dl_malloc(2); + if (retval[pos] == NULL) + goto badret; + + _dl_bcopy(".", retval[pos++], 2); + } else { + retval[pos] = _dl_malloc(pp - p_begin + 1); + if (retval[pos] == NULL) + goto badret; + + _dl_bcopy(p_begin, retval[pos], pp - p_begin); + retval[pos++][pp - p_begin] = '\0'; + } + + if (*pp) /* Try curdir if ':' at end */ + pp++; + else + pp = NULL; + } + + return (retval); + +badret: + _dl_free_path(retval); + return (NULL); +} + +void +_dl_free_path(char **path) +{ + char **p = path; + + if (path == NULL) + return; + + while (*p != NULL) + _dl_free(*p++); + + _dl_free(path); +} diff --git a/libexec/ld.so/path.h b/libexec/ld.so/path.h new file mode 100644 index 00000000000..e8bf9fdd613 --- /dev/null +++ b/libexec/ld.so/path.h @@ -0,0 +1,25 @@ +/* $OpenBSD: path.h,v 1.1 2013/03/20 21:49:59 kurt Exp $ */ + +/* + * Copyright (c) 2013 Kurt Miller <kurt@intricatesoftware.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __DL_PATH_H__ +#define __DL_PATH_H__ + +char ** _dl_split_path(const char *searchpath); +void _dl_free_path(char **path); + +#endif /*__DL_PATH_H__*/ diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index ecd2e975d51..f2ba69332dc 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.59 2012/07/06 23:15:50 matthew Exp $ */ +/* $OpenBSD: resolve.c,v 1.60 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -34,6 +34,7 @@ #include <link.h> #include "syscall.h" #include "archdep.h" +#include "path.h" #include "resolve.h" #include "dl_prebind.h" @@ -182,6 +183,9 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, Elf_Phdr *phdrp, TAILQ_INIT(&object->grpsym_list); TAILQ_INIT(&object->grpref_list); + if (object->dyn.rpath) + object->rpath = _dl_split_path(object->dyn.rpath); + return(object); } @@ -223,6 +227,8 @@ _dl_cleanup_objects() _dl_free(head->load_name); if (head->sod.sod_name) _dl_free((char *)head->sod.sod_name); + if (head->rpath) + _dl_free_path(head->rpath); _dl_tailq_free(TAILQ_FIRST(&head->grpsym_list)); _dl_tailq_free(TAILQ_FIRST(&head->child_list)); _dl_tailq_free(TAILQ_FIRST(&head->grpref_list)); diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index d0f6bbd5b43..9b566e62c11 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.65 2011/11/28 20:59:03 guenther Exp $ */ +/* $OpenBSD: resolve.h,v 1.66 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -149,6 +149,8 @@ struct elf_object { /* last symbol lookup on this object, to avoid mutiple searches */ int lastlookup_head; int lastlookup; + + char **rpath; }; struct dep_node { @@ -223,7 +225,7 @@ void _dl_run_all_dtors(void); Elf_Addr _dl_bind(elf_object_t *object, int index); int _dl_match_file(struct sod *sodp, const char *name, int namelen); -char *_dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints); +char *_dl_find_shlib(struct sod *sodp, char **searchpath, int nohints); void _dl_load_list_free(struct load_list *load_list); void _dl_thread_kern_go(void); @@ -242,7 +244,8 @@ extern struct r_debug *_dl_debug_map; extern int _dl_pagesz; extern int _dl_errno; -extern char *_dl_libpath; +extern char **_dl_libpath; + extern char *_dl_preload; extern char *_dl_bindnow; extern char *_dl_traceld; diff --git a/libexec/ld.so/sod.c b/libexec/ld.so/sod.c index 5fc908853c4..e2d6711e6a3 100644 --- a/libexec/ld.so/sod.c +++ b/libexec/ld.so/sod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sod.c,v 1.25 2013/01/19 20:04:05 miod Exp $ */ +/* $OpenBSD: sod.c,v 1.26 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 1993 Paul Kranenburg @@ -46,6 +46,7 @@ #include "syscall.h" #include "archdep.h" +#include "path.h" #include "util.h" #include "sod.h" @@ -146,7 +147,7 @@ _dl_set_sod(const char *path, struct sod *sod) static struct hints_header *hheader = NULL; static struct hints_bucket *hbuckets; static char *hstrtab; -char *_dl_hint_search_path = NULL; +char **_dl_hint_search_path = NULL; #define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1) @@ -181,7 +182,7 @@ _dl_maphints(void) hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab); hstrtab = (char *)(addr + hheader->hh_strtab); if (hheader->hh_version >= LD_HINTS_VERSION_2) - _dl_hint_search_path = hstrtab + hheader->hh_dirlist; + _dl_hint_search_path = _dl_split_path(hstrtab + hheader->hh_dirlist); /* close the file descriptor, leaving the hints mapped */ _dl_close(hfd); diff --git a/libexec/ld.so/sod.h b/libexec/ld.so/sod.h index e7dc3bc4fa4..325c46cd855 100644 --- a/libexec/ld.so/sod.h +++ b/libexec/ld.so/sod.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sod.h,v 1.2 2012/06/12 20:32:17 matthew Exp $ */ +/* $OpenBSD: sod.h,v 1.3 2013/03/20 21:49:59 kurt Exp $ */ /* * Copyright (c) 1993 Paul Kranenburg @@ -34,4 +34,4 @@ void _dl_build_sod(const char *name, struct sod *sodp); void _dl_set_sod(const char *, struct sod *); char *_dl_findhint(char *name, int major, int minor, char *prefered_path); -extern char *_dl_hint_search_path; +extern char **_dl_hint_search_path; |