summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2013-03-20 21:50:00 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2013-03-20 21:50:00 +0000
commit9908e967b5ddb41570e5863703c45ffb3fbab784 (patch)
treeadbd217af63153653339d5e162ec9e46ca3fc859 /libexec
parent105cb62bdd35500a8491e586d2e7d4cb46729185 (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/Makefile4
-rw-r--r--libexec/ld.so/ldconfig/Makefile4
-rw-r--r--libexec/ld.so/ldconfig/ldconfig.84
-rw-r--r--libexec/ld.so/ldconfig/library.c78
-rw-r--r--libexec/ld.so/ldconfig/prebind.c7
-rw-r--r--libexec/ld.so/ldconfig/prebind_path.c38
-rw-r--r--libexec/ld.so/ldconfig/sod.c7
-rw-r--r--libexec/ld.so/library_subr.c71
-rw-r--r--libexec/ld.so/loader.c11
-rw-r--r--libexec/ld.so/path.c98
-rw-r--r--libexec/ld.so/path.h25
-rw-r--r--libexec/ld.so/resolve.c8
-rw-r--r--libexec/ld.so/resolve.h9
-rw-r--r--libexec/ld.so/sod.c7
-rw-r--r--libexec/ld.so/sod.h4
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;