diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2013-04-05 12:58:05 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2013-04-05 12:58:05 +0000 |
commit | 1892e71c11ce0b9f666c92574ed7161d16dc08f8 (patch) | |
tree | 755a6b60e7d08a717e59ceed6909b1d2aeefdeeb /libexec/ld.so | |
parent | 84c7c115879a734ff013eca4de8f5ac17c120b9c (diff) |
- Add ORIGIN, OSNAME, OSREL and PLATFORM substitution support for rpaths.
Improvements and okay matthew@, millert@, guenther@
Diffstat (limited to 'libexec/ld.so')
30 files changed, 834 insertions, 41 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile index 69eb5c23c71..a100c590c16 100644 --- a/libexec/ld.so/Makefile +++ b/libexec/ld.so/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.42 2013/03/20 21:49:59 kurt Exp $ +# $OpenBSD: Makefile,v 1.43 2013/04/05 12:58:03 kurt Exp $ SUBDIR=ldconfig ldd MAN= ld.so.1 @@ -16,6 +16,7 @@ VPATH=${.CURDIR}/../../lib/libc/string 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 +SRCS+= dl_realpath.c dl_uname.c dl_dirname.c strlcat.c strlen.c .if (${MACHINE_ARCH} == "i386") SRCS+= library_mquery.c .else @@ -29,7 +30,7 @@ SRCS+= library.c DEBUG?= -g CFLAGS += -Wall -Werror CFLAGS += -I${.CURDIR} -I${.CURDIR}/${MACHINE_CPU} \ - -Dstrsep=_dl_strsep + -Dstrsep=_dl_strsep -Dstrlcat=_dl_strlcat -Dstrlen=_dl_strlen CDIAGFLAGS= INSTALL_STRIP= diff --git a/libexec/ld.so/alpha/ldasm.S b/libexec/ld.so/alpha/ldasm.S index 0806b4312e9..6264cd5f7f1 100644 --- a/libexec/ld.so/alpha/ldasm.S +++ b/libexec/ld.so/alpha/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.18 2012/10/24 03:26:55 guenther Exp $ */ +/* $OpenBSD: ldasm.S,v 1.19 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -307,3 +307,21 @@ LEAF_NOPROFILE(_dl_gettimeofday, 2) RET END(_dl_gettimeofday) +LEAF_NOPROFILE(_dl_readlink, 3) + ldiq v0, SYS_readlink + call_pal PAL_OSF1_callsys + RET +END(_dl_readlink) + +LEAF_NOPROFILE(_dl_lstat, 2) + ldiq v0, SYS_lstat + call_pal PAL_OSF1_callsys + RET +END(_dl_lstat) + +LEAF_NOPROFILE(_dl_getcwd, 2) + ldiq v0, SYS___getcwd + call_pal PAL_OSF1_callsys + RET +END(_dl_getcwd) + diff --git a/libexec/ld.so/alpha/syscall.h b/libexec/ld.so/alpha/syscall.h index d7699c9449e..c5d48531659 100644 --- a/libexec/ld.so/alpha/syscall.h +++ b/libexec/ld.so/alpha/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.18 2012/10/24 03:26:55 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.19 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ long _dl__syscall(quad_t, ...); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/amd64/ldasm.S b/libexec/ld.so/amd64/ldasm.S index ec3d77b696f..54351727872 100644 --- a/libexec/ld.so/amd64/ldasm.S +++ b/libexec/ld.so/amd64/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.10 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: ldasm.S,v 1.11 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2002,2004 Dale Rahn @@ -95,6 +95,9 @@ DL_SYSCALL(mprotect) DL_SYSCALL(munmap) DL_SYSCALL(gettimeofday) DL_SYSCALL(exit) +DL_SYSCALL(readlink) +DL_SYSCALL(lstat) +DL_SYSCALL2(getcwd,__getcwd) DL_SYSCALL2(_syscall,__syscall) DL_SYSCALL2(sysctl,__sysctl) diff --git a/libexec/ld.so/amd64/syscall.h b/libexec/ld.so/amd64/syscall.h index b96dc87f530..9cf7dc62c14 100644 --- a/libexec/ld.so/amd64/syscall.h +++ b/libexec/ld.so/amd64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.6 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.7 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/arm/ldasm.S b/libexec/ld.so/arm/ldasm.S index a6729bbcd97..6d3bcf08bf8 100644 --- a/libexec/ld.so/arm/ldasm.S +++ b/libexec/ld.so/arm/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.8 2012/12/22 11:46:16 kettenis Exp $ */ +/* $OpenBSD: ldasm.S,v 1.9 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -114,6 +114,9 @@ DL_SYSCALL(write) DL_SYSCALL(fstat) DL_SYSCALL(fcntl) DL_SYSCALL(gettimeofday) +DL_SYSCALL(readlink) +DL_SYSCALL(lstat) +DL_SYSCALL2(getcwd,__getcwd) DL_SYSCALL2(sysctl,__sysctl) DL_SYSCALL(getdirentries) diff --git a/libexec/ld.so/arm/syscall.h b/libexec/ld.so/arm/syscall.h index 27347f7e992..b46b170782c 100644 --- a/libexec/ld.so/arm/syscall.h +++ b/libexec/ld.so/arm/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.6 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.7 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/dl_dirname.c b/libexec/ld.so/dl_dirname.c new file mode 100644 index 00000000000..6079ce9c1a2 --- /dev/null +++ b/libexec/ld.so/dl_dirname.c @@ -0,0 +1,70 @@ +/* $OpenBSD: dl_dirname.c,v 1.1 2013/04/05 12:58:03 kurt Exp $ */ + +/* + * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.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/param.h> + +#include "archdep.h" + +/* + * This file was copied from libc/stdlib/realpath.c and modified for ld.so's + * syscall method which returns -errno. + */ + +char * +_dl_dirname(const char *path) +{ + static char dname[MAXPATHLEN]; + size_t len; + const char *endp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + dname[0] = '.'; + dname[1] = '\0'; + return (dname); + } + + /* Strip any trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + dname[0] = *endp == '/' ? '/' : '.'; + dname[1] = '\0'; + return (dname); + } else { + /* Move forward past the separating slashes */ + do { + endp--; + } while (endp > path && *endp == '/'); + } + + len = endp - path + 1; + if (len >= sizeof(dname)) { + return (NULL); + } + _dl_bcopy(path, dname, len); + dname[len] = '\0'; + return (dname); +} diff --git a/libexec/ld.so/dl_realpath.c b/libexec/ld.so/dl_realpath.c new file mode 100644 index 00000000000..b568da91abe --- /dev/null +++ b/libexec/ld.so/dl_realpath.c @@ -0,0 +1,205 @@ +/* $OpenBSD: dl_realpath.c,v 1.1 2013/04/05 12:58:03 kurt Exp $ */ +/* + * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <limits.h> +#include "archdep.h" + +#define ENOENT -2 + +/* + * This file was copied from libc/stdlib/realpath.c and modified for ld.so's + * syscall method which returns -errno. + */ + +/* + * char *dl_realpath(const char *path, char resolved[PATH_MAX]); + * + * Find the real name of path, by removing all ".", ".." and symlink + * components. Returns (resolved) on success, or (NULL) on failure, + * in which case the path which caused trouble is left in (resolved). + */ +char * +_dl_realpath(const char *path, char *resolved) +{ + struct stat sb; + const char *p, *s; + char *q; + size_t left_len, resolved_len; + unsigned symlinks; + int slen, mem_allocated, ret; + char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; + + if (path[0] == '\0') { + return (NULL); + } + + if (resolved == NULL) { + resolved = _dl_malloc(PATH_MAX); + if (resolved == NULL) + return (NULL); + mem_allocated = 1; + } else + mem_allocated = 0; + + symlinks = 0; + if (path[0] == '/') { + resolved[0] = '/'; + resolved[1] = '\0'; + if (path[1] == '\0') + return (resolved); + resolved_len = 1; + left_len = _dl_strlcpy(left, path + 1, sizeof(left)); + } else { + if (_dl_getcwd(resolved, PATH_MAX) <= 0) { + if (mem_allocated) + _dl_free(resolved); + else + _dl_strlcpy(resolved, ".", PATH_MAX); + return (NULL); + } + resolved_len = _dl_strlen(resolved); + left_len = _dl_strlcpy(left, path, sizeof(left)); + } + if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { + goto err; + } + + /* + * Iterate over path components in `left'. + */ + while (left_len != 0) { + /* + * Extract the next path component and adjust `left' + * and its length. + */ + p = _dl_strchr(left, '/'); + s = p ? p : left + left_len; + if (s - left >= sizeof(next_token)) { + goto err; + } + _dl_bcopy(left, next_token, s - left); + next_token[s - left] = '\0'; + left_len -= s - left; + if (p != NULL) + _dl_bcopy(s + 1, left, left_len + 1); + if (resolved[resolved_len - 1] != '/') { + if (resolved_len + 1 >= PATH_MAX) { + goto err; + } + resolved[resolved_len++] = '/'; + resolved[resolved_len] = '\0'; + } + if (next_token[0] == '\0') + continue; + else if (_dl_strcmp(next_token, ".") == 0) + continue; + else if (_dl_strcmp(next_token, "..") == 0) { + /* + * Strip the last path component except when we have + * single "/" + */ + if (resolved_len > 1) { + resolved[resolved_len - 1] = '\0'; + q = _dl_strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + continue; + } + + /* + * Append the next path component and lstat() it. If + * lstat() fails we still can return successfully if + * there are no more path components left. + */ + resolved_len = _dl_strlcat(resolved, next_token, PATH_MAX); + if (resolved_len >= PATH_MAX) { + goto err; + } + if ((ret = _dl_lstat(resolved, &sb)) != 0) { + if (ret == ENOENT && p == NULL) { + return (resolved); + } + goto err; + } + if (S_ISLNK(sb.st_mode)) { + if (symlinks++ > SYMLOOP_MAX) { + goto err; + } + slen = _dl_readlink(resolved, symlink, sizeof(symlink) - 1); + if (slen < 0) + goto err; + symlink[slen] = '\0'; + if (symlink[0] == '/') { + resolved[1] = 0; + resolved_len = 1; + } else if (resolved_len > 1) { + /* Strip the last path component. */ + resolved[resolved_len - 1] = '\0'; + q = _dl_strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + + /* + * If there are any path components left, then + * append them to symlink. The result is placed + * in `left'. + */ + if (p != NULL) { + if (symlink[slen - 1] != '/') { + if (slen + 1 >= sizeof(symlink)) { + goto err; + } + symlink[slen] = '/'; + symlink[slen + 1] = 0; + } + left_len = _dl_strlcat(symlink, left, sizeof(symlink)); + if (left_len >= sizeof(left)) { + goto err; + } + } + left_len = _dl_strlcpy(left, symlink, sizeof(left)); + } + } + + /* + * Remove trailing slash except when the resolved pathname + * is a single "/". + */ + if (resolved_len > 1 && resolved[resolved_len - 1] == '/') + resolved[resolved_len - 1] = '\0'; + return (resolved); + +err: + if (mem_allocated) + _dl_free(resolved); + return (NULL); +} diff --git a/libexec/ld.so/dl_uname.c b/libexec/ld.so/dl_uname.c new file mode 100644 index 00000000000..1d35e2ad6b6 --- /dev/null +++ b/libexec/ld.so/dl_uname.c @@ -0,0 +1,69 @@ +/* $OpenBSD: dl_uname.c,v 1.1 2013/04/05 12:58:03 kurt Exp $ */ +/* + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/utsname.h> + +#include "archdep.h" + +/* + * This file was copied from libc/gen/uname.c and modified for ld.so's + * syscall method which returns -errno. Also KERN_OSVERSION is not retrieved + * since ld.so doesn't need it. + */ + +int +_dl_uname(struct utsname *name) +{ + int mib[2], rval; + size_t len; + + rval = 0; + + mib[0] = CTL_KERN; + mib[1] = KERN_OSTYPE; + len = sizeof(name->sysname); + if (_dl_sysctl(mib, 2, &name->sysname, &len, NULL, 0) < 0) + rval = -1; + + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + len = sizeof(name->release); + if (_dl_sysctl(mib, 2, &name->release, &len, NULL, 0) < 0) + rval = -1; + + mib[0] = CTL_HW; + mib[1] = HW_MACHINE; + len = sizeof(name->machine); + if (_dl_sysctl(mib, 2, &name->machine, &len, NULL, 0) < 0) + rval = -1; + return (rval); +} diff --git a/libexec/ld.so/hppa/ldasm.S b/libexec/ld.so/hppa/ldasm.S index be3604d3fec..644b0ddfa60 100644 --- a/libexec/ld.so/hppa/ldasm.S +++ b/libexec/ld.so/hppa/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.8 2012/10/27 08:30:35 kettenis Exp $ */ +/* $OpenBSD: ldasm.S,v 1.9 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2004 Michael Shalayeff @@ -263,6 +263,24 @@ ENTRY(_dl_gettimeofday,0) nop EXIT(_dl_gettimeofday) +ENTRY(_dl_readlink,0) + SYSCALL(readlink) + bv r0(rp) + nop +EXIT(_dl_readlink) + +ENTRY(_dl_lstat,0) + SYSCALL(lstat) + bv r0(rp) + nop +EXIT(_dl_lstat) + +ENTRY(_dl_getcwd,0) + SYSCALL(__getcwd) + bv r0(rp) + nop +EXIT(_dl_getcwd) + ENTRY(_dl_sigprocmask,0) stw arg2, HPPA_FRAME_ARG(2)(sp) diff --git a/libexec/ld.so/hppa/syscall.h b/libexec/ld.so/hppa/syscall.h index b96dc87f530..9cf7dc62c14 100644 --- a/libexec/ld.so/hppa/syscall.h +++ b/libexec/ld.so/hppa/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.6 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.7 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/i386/ldasm.S b/libexec/ld.so/i386/ldasm.S index dac6d208c87..149bbe76494 100644 --- a/libexec/ld.so/i386/ldasm.S +++ b/libexec/ld.so/i386/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.12 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: ldasm.S,v 1.13 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -117,6 +117,9 @@ DL_SYSCALL(write) DL_SYSCALL(fstat) DL_SYSCALL(fcntl) DL_SYSCALL(gettimeofday) +DL_SYSCALL(readlink) +DL_SYSCALL(lstat) +DL_SYSCALL2(getcwd,__getcwd) DL_SYSCALL2(sysctl,__sysctl) DL_SYSCALL(getdirentries) diff --git a/libexec/ld.so/i386/syscall.h b/libexec/ld.so/i386/syscall.h index 9629dcb311b..68f72f6941e 100644 --- a/libexec/ld.so/i386/syscall.h +++ b/libexec/ld.so/i386/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.10 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.11 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index 8e6ac3ce016..fdda79de64c 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.131 2013/03/20 21:49:59 kurt Exp $ */ +/* $OpenBSD: loader.c,v 1.132 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -76,6 +76,8 @@ char *_dl_noprebind; char *_dl_prebind_validate; char *_dl_tracefmt1, *_dl_tracefmt2, *_dl_traceprog; +int _dl_trust; + struct r_debug *_dl_debug_map; void _dl_dopreload(char *paths); @@ -230,7 +232,8 @@ _dl_setup_env(char **envp) * Don't allow someone to change the search paths if he runs * a suid program without credentials high enough. */ - if (_dl_issetugid()) { /* Zap paths if s[ug]id... */ + _dl_trust = !_dl_issetugid(); + if (!_dl_trust) { /* Zap paths if s[ug]id... */ if (_dl_libpath) { _dl_free_path(_dl_libpath); _dl_libpath = NULL; diff --git a/libexec/ld.so/m68k/ldasm.S b/libexec/ld.so/m68k/ldasm.S index 2b51a95b73f..59a647435ea 100644 --- a/libexec/ld.so/m68k/ldasm.S +++ b/libexec/ld.so/m68k/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.2 2013/02/02 13:37:02 miod Exp $ */ +/* $OpenBSD: ldasm.S,v 1.3 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2006 Dale Rahn @@ -176,6 +176,15 @@ DL_SYSCALL(fcntl) DL_SYSCALL(gettimeofday) rts +DL_SYSCALL(readlink) + rts + +DL_SYSCALL(lstat) + rts + +DL_SYSCALL2(getcwd,__getcwd) + rts + DL_SYSCALL2(sysctl,__sysctl) rts diff --git a/libexec/ld.so/m68k/syscall.h b/libexec/ld.so/m68k/syscall.h index 656445e3937..e635a3be102 100644 --- a/libexec/ld.so/m68k/syscall.h +++ b/libexec/ld.so/m68k/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.1 2013/01/23 19:15:58 miod Exp $ */ +/* $OpenBSD: syscall.h,v 1.2 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/m88k/ldasm.S b/libexec/ld.so/m88k/ldasm.S index 2e2f8382b87..3633da6a64f 100644 --- a/libexec/ld.so/m88k/ldasm.S +++ b/libexec/ld.so/m88k/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.4 2013/01/26 20:40:42 miod Exp $ */ +/* $OpenBSD: ldasm.S,v 1.5 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2013 Miodrag Vallat. @@ -197,6 +197,15 @@ DL_SYSCALL(fcntl) DL_SYSCALL(gettimeofday) jmp %r1 +DL_SYSCALL(readlink) + jmp %r1 + +DL_SYSCALL(lstat) + jmp %r1 + +DL_SYSCALL2(getcwd,__getcwd) + jmp %r1 + DL_SYSCALL2(sysctl,__sysctl) jmp %r1 diff --git a/libexec/ld.so/m88k/syscall.h b/libexec/ld.so/m88k/syscall.h index dade9bbf74a..981c5d6e5ce 100644 --- a/libexec/ld.so/m88k/syscall.h +++ b/libexec/ld.so/m88k/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.2 2013/01/23 19:01:44 miod Exp $ */ +/* $OpenBSD: syscall.h,v 1.3 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/mips64/syscall.h b/libexec/ld.so/mips64/syscall.h index 51128092656..d0316c15ff1 100644 --- a/libexec/ld.so/mips64/syscall.h +++ b/libexec/ld.so/mips64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.8 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.9 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 1998-2002 Opsycon AB, Sweden. @@ -295,6 +295,7 @@ _dl_sigprocmask(int how, const sigset_t *set, sigset_t *oset) return 0; } + static inline int _dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp, size_t newlen) @@ -320,6 +321,7 @@ _dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp, "$10","$11","$12","$13","$14","$15","$24","$25"); return status; } + extern inline int _dl_gettimeofday(struct timeval* tp, struct timezone *tzp) { @@ -340,4 +342,65 @@ _dl_gettimeofday(struct timeval* tp, struct timezone *tzp) return status; } +extern inline int +_dl_readlink(const char *path, char *buf, size_t bufsiz) +{ + register int status __asm__ ("$2"); + + __asm__ volatile ( + "move $4,%2\n\t" + "move $5,%3\n\t" + "move $6,%4\n\t" + "li $2,%1\n\t" + "syscall\n\t" + "beq $7,$0,1f\n\t" + "li $2,-1\n\t" + "1:" + : "=r" (status) + : "I" (SYS_readlink), "r" (path), "r" (buf), "r" (bufsiz) + : "memory", "$3", "$4", "$5", "$6", "$7", "$8", "$9", + "$10","$11","$12","$13","$14","$15","$24","$25"); + return status; +} + +extern inline int +_dl_lstat(const char *path, struct stat *sb) +{ + register int status __asm__ ("$2"); + + __asm__ volatile ( + "move $4,%2\n\t" + "move $5,%3\n\t" + "li $2,%1\n\t" + "syscall\n\t" + "beq $7,$0,1f\n\t" + "li $2,-1\n\t" + "1:" + : "=r" (status) + : "I" (SYS_lstat), "r" (path), "r" (sb) + : "memory", "$3", "$4", "$5", "$6", "$7", "$8", "$9", + "$10","$11","$12","$13","$14","$15","$24","$25"); + return status; +} + +static inline int +_dl_getcwd(char *buf, size_t size) +{ + register int status __asm__ ("$2"); + + __asm__ volatile ( + "move $4,%2\n\t" + "move $5,%3\n\t" + "li $2,%1\n\t" + "syscall\n\t" + "beq $7,$0,1f\n\t" + "li $2,-1\n\t" + "1:" + : "=r" (status) + : "I" (SYS___getcwd), "r" (buf), "r" (size) + : "memory", "$3", "$4", "$5", "$6", "$7", "$8", "$9", + "$10","$11","$12","$13","$14","$15","$24","$25"); + return status; +} + #endif /*__DL_SYSCALL_H__*/ diff --git a/libexec/ld.so/powerpc/syscall.h b/libexec/ld.so/powerpc/syscall.h index 4d7b4bc16f9..3463d2a5d9f 100644 --- a/libexec/ld.so/powerpc/syscall.h +++ b/libexec/ld.so/powerpc/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.24 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.25 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -308,6 +308,7 @@ _dl_sigprocmask(int how, const sigset_t *set, sigset_t *oset) return 0; } + static inline int _dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp, size_t newlen) @@ -333,6 +334,7 @@ _dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp, : "memory", "0", "3", "4", "5", "6", "7", "8"); return status; } + static inline int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp) { @@ -353,6 +355,66 @@ _dl_gettimeofday(struct timeval *tp, struct timezone *tzp) return status; } +static inline int +_dl_readlink(const char *path, char *buf, size_t bufsiz) +{ + register int status; + + __asm__ volatile ("li 0,%1\n\t" + "mr 3,%2\n\t" + "mr 4,%3\n\t" + "mr 5,%4\n\t" + "sc\n\t" + "cmpwi 0, 0\n\t" + "beq 1f\n\t" + "li 3,-1\n\t" + "1:" + "mr %0,3\n\t" + : "=r" (status) + : "I" (SYS_readlink), "r" (path), "r" (buf), "r" (bufsiz) + : "memory", "0", "3", "4", "5"); + return status; +} + +static inline int +_dl_lstat(const char *path, struct stat *sb) +{ + register int status; + + __asm__ volatile ("li 0,%1\n\t" + "mr 3,%2\n\t" + "mr 4,%3\n\t" + "sc\n\t" + "cmpwi 0, 0\n\t" + "beq 1f\n\t" + "li 3,-1\n\t" + "1:" + "mr %0,3\n\t" + : "=r" (status) + : "I" (SYS_lstat), "r" (path), "r" (sb) + : "memory", "0", "3", "4" ); + return status; +} + +static inline int +_dl_getcwd(char *buf, size_t size) +{ + register int status; + + __asm__ volatile ("li 0,%1\n\t" + "mr 3,%2\n\t" + "mr 4,%3\n\t" + "sc\n\t" + "cmpwi 0, 0\n\t" + "beq 1f\n\t" + "li 3,-1\n\t" + "1:" + "mr %0,3\n\t" + : "=r" (status) + : "I" (SYS___getcwd), "r" (buf), "r" (size) + : "0", "3", "4"); + return status; +} #endif /*__DL_SYSCALL_H__*/ diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index f2ba69332dc..8a232c88a32 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.60 2013/03/20 21:49:59 kurt Exp $ */ +/* $OpenBSD: resolve.c,v 1.61 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -30,6 +30,7 @@ #include <sys/types.h> +#include <limits.h> #include <nlist.h> #include <link.h> #include "syscall.h" @@ -38,6 +39,11 @@ #include "resolve.h" #include "dl_prebind.h" +/* substitution types */ +typedef enum { + SUBST_UNKNOWN, SUBST_ORIGIN, SUBST_OSNAME, SUBST_OSREL, SUBST_PLATFORM +} SUBST_TYPES; + elf_object_t *_dl_objects; elf_object_t *_dl_last_object; elf_object_t *_dl_loading_object; @@ -75,6 +81,159 @@ _dl_add_object(elf_object_t *object) } /* + * Identify substitution sequence name. + */ +static int +_dl_subst_name(const char *name, size_t siz) { + switch (siz) { + case 5: + if (_dl_strncmp(name, "OSREL", 5) == 0) + return SUBST_OSREL; + break; + case 6: + if (_dl_strncmp(name, "ORIGIN", 6) == 0) + return SUBST_ORIGIN; + if (_dl_strncmp(name, "OSNAME", 6) == 0) + return SUBST_OSNAME; + break; + case 8: + if (_dl_strncmp(name, "PLATFORM", 8) == 0) + return SUBST_PLATFORM; + break; + } + + return (SUBST_UNKNOWN); +} + +/* + * Perform $ORIGIN substitutions on path + */ +static void +_dl_origin_subst_path(elf_object_t *object, const char *origin_path, + char **path) +{ + char tmp_path[PATH_MAX]; + char *new_path, *tp; + const char *pp, *name, *value; + static struct utsname uts; + size_t value_len; + int skip_brace; + + if (uts.sysname[0] == '\0') { + if (_dl_uname(&uts) != 0) + return; + } + + tp = tmp_path; + pp = *path; + + while (*pp != '\0' && (tp - tmp_path) < sizeof(tmp_path)) { + + /* copy over chars up to but not including $ */ + while (*pp != '\0' && *pp != '$' && + (tp - tmp_path) < sizeof(tmp_path)) + *tp++ = *pp++; + + /* substitution sequence detected */ + if (*pp == '$' && (tp - tmp_path) < sizeof(tmp_path)) { + pp++; + + if ((skip_brace = (*pp == '{'))) + pp++; + + /* skip over name */ + name = pp; + while (_dl_isalnum(*pp) || *pp == '_') + pp++; + + switch (_dl_subst_name(name, pp - name)) { + case SUBST_ORIGIN: + value = origin_path; + break; + case SUBST_OSNAME: + value = uts.sysname; + break; + case SUBST_OSREL: + value = uts.release; + break; + case SUBST_PLATFORM: + value = uts.machine; + break; + default: + value = ""; + } + + value_len = _dl_strlen(value); + if (value_len >= sizeof(tmp_path) - (tp - tmp_path)) + return; + + _dl_bcopy(value, tp, value_len); + tp += value_len; + + if (skip_brace && *pp == '}') + pp++; + } + } + + /* no substitution made if result exceeds sizeof(tmp_path) */ + if (tp - tmp_path >= sizeof(tmp_path)) + return; + + /* NULL terminate tmp_path */ + *tp = '\0'; + + if (_dl_strcmp(tmp_path, *path) == 0) + return; + + new_path = _dl_strdup(tmp_path); + if (new_path == NULL) + return; + + DL_DEB(("orig_path %s\n", *path)); + DL_DEB(("new_path %s\n", new_path)); + + _dl_free(*path); + *path = new_path; +} + +/* + * Determine origin_path from object load_name. The origin_path argument + * must refer to a buffer capable of storing at least PATH_MAX characters. + * Returns 0 on success. + */ +static int +_dl_origin_path(elf_object_t *object, char *origin_path) +{ + const char *dirname_path = _dl_dirname(object->load_name); + + if (dirname_path == NULL) + return -1; + + if (_dl_realpath(dirname_path, origin_path) == NULL) + return -1; + + return 0; +} + +/* + * Perform $ORIGIN substitutions on rpath + */ +static void +_dl_origin_subst(elf_object_t *object) +{ + char origin_path[PATH_MAX]; + char **pp; + + if (_dl_origin_path(object, origin_path) != 0) + return; + + /* perform path substitutions on each segment of rpath */ + for (pp = object->rpath; *pp != NULL; pp++) { + _dl_origin_subst_path(object, origin_path, pp); + } +} + +/* * Initialize a new dynamic object. */ elf_object_t * @@ -183,10 +342,13 @@ _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) + if (object->dyn.rpath) { object->rpath = _dl_split_path(object->dyn.rpath); + if ((object->obj_flags & DF_1_ORIGIN) && _dl_trust) + _dl_origin_subst(object); + } - return(object); + return (object); } void diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index 9b566e62c11..3ebfe7061d5 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.66 2013/03/20 21:49:59 kurt Exp $ */ +/* $OpenBSD: resolve.h,v 1.67 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -254,6 +254,8 @@ extern char *_dl_tracefmt2; extern char *_dl_traceprog; extern char *_dl_debug; +extern int _dl_trust; + #define DL_DEB(P) do { if (_dl_debug) _dl_printf P ; } while (0) #define DL_NOT_FOUND 1 diff --git a/libexec/ld.so/sh/ldasm.S b/libexec/ld.so/sh/ldasm.S index 29dad9de690..09c11e6825d 100644 --- a/libexec/ld.so/sh/ldasm.S +++ b/libexec/ld.so/sh/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.9 2012/11/01 10:25:33 kettenis Exp $ */ +/* $OpenBSD: ldasm.S,v 1.10 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2006 Dale Rahn @@ -195,6 +195,9 @@ DL_SYSCALL(write) DL_SYSCALL(fstat) DL_SYSCALL(fcntl) DL_SYSCALL(gettimeofday) +DL_SYSCALL(readlink) +DL_SYSCALL(lstat) +DL_SYSCALL2(getcwd,__getcwd) DL_SYSCALL2(sysctl,__sysctl) DL_SYSCALL(getdirentries) diff --git a/libexec/ld.so/sh/syscall.h b/libexec/ld.so/sh/syscall.h index fddd0a820dd..7ef83f0871e 100644 --- a/libexec/ld.so/sh/syscall.h +++ b/libexec/ld.so/sh/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.4 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.5 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/sparc/ldasm.S b/libexec/ld.so/sparc/ldasm.S index 028b07dc5a3..cda4c8810d2 100644 --- a/libexec/ld.so/sparc/ldasm.S +++ b/libexec/ld.so/sparc/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.18 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: ldasm.S,v 1.19 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -318,6 +318,43 @@ _dl_gettimeofday: retl sub %g0, %o0, %o0 ! error: result = -errno + + .section ".text" + .align 4 + .global _dl_readlink + .type _dl_readlink,@function +_dl_readlink: + mov SYS_readlink | SYSCALL_G2RFLAG, %g1 ! calling sys_readlink + add %o7, 8, %g2 ! just return on success + t ST_SYSCALL ! off to wonderland + retl + sub %g0, %o0, %o0 ! error: result = -errno + + + .section ".text" + .align 4 + .global _dl_lstat + .type _dl_lstat,@function +_dl_lstat: + mov SYS_lstat | SYSCALL_G2RFLAG, %g1 ! calling sys_lstat + add %o7, 8, %g2 ! just return on success + t ST_SYSCALL ! off to wonderland + retl + sub %g0, %o0, %o0 ! error: result = -errno + + + .section ".text" + .align 4 + .global _dl_getcwd + .type _dl_getcwd,@function +_dl_getcwd: + mov SYS___getcwd | SYSCALL_G2RFLAG, %g1 ! calling sys_getcwd + add %o7, 8, %g2 ! just return on success + t ST_SYSCALL ! off to wonderland + retl + sub %g0, %o0, %o0 ! error: result = -errno + + /* * V8 sparc .{,u}{mul,div,rem} replacements. * We try to mimic them 100%. Full 64 bit sources or outputs, and diff --git a/libexec/ld.so/sparc/syscall.h b/libexec/ld.so/sparc/syscall.h index 9335fe2c6c5..9e57c300d59 100644 --- a/libexec/ld.so/sparc/syscall.h +++ b/libexec/ld.so/sparc/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.11 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.12 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/sparc64/ldasm.S b/libexec/ld.so/sparc64/ldasm.S index f23719ea789..92721d86de6 100644 --- a/libexec/ld.so/sparc64/ldasm.S +++ b/libexec/ld.so/sparc64/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.29 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: ldasm.S,v 1.30 2013/04/05 12:58:03 kurt Exp $ */ /* $NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $ */ /* @@ -315,3 +315,24 @@ _ENTRY(_dl_gettimeofday) retl sub %g0, %o0, %o0 ! error: result = -errno +_ENTRY(_dl_readlink) + mov SYS_readlink | SYSCALL_G2RFLAG, %g1 ! calling sys_readlink + add %o7, 8, %g2 ! just return on success + t ST_SYSCALL ! off to wonderland + retl + sub %g0, %o0, %o0 ! error: result = -errno + +_ENTRY(_dl_lstat) + mov SYS_lstat | SYSCALL_G2RFLAG, %g1 ! calling sys_lstat + add %o7, 8, %g2 ! just return on success + t ST_SYSCALL ! off to wonderland + retl + sub %g0, %o0, %o0 ! error: result = -errno + +_ENTRY(_dl_getcwd) + mov SYS___getcwd | SYSCALL_G2RFLAG, %g1 ! calling sys___getcwd + add %o7, 8, %g2 ! just return on success + t ST_SYSCALL ! off to wonderland + retl + sub %g0, %o0, %o0 ! error: result = -errno + diff --git a/libexec/ld.so/sparc64/syscall.h b/libexec/ld.so/sparc64/syscall.h index 91240a4a5f1..2b7c1192c57 100644 --- a/libexec/ld.so/sparc64/syscall.h +++ b/libexec/ld.so/sparc64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.18 2012/10/24 03:26:56 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.19 2013/04/05 12:58:04 kurt Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *); int _dl_sigprocmask(int, const sigset_t *, sigset_t *); int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t); int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp); +int _dl_readlink(const char *path, char *buf, size_t bufsiz); +int _dl_lstat(const char *path, struct stat *sb); +int _dl_getcwd(char *buf, size_t size); static inline off_t _dl_lseek(int fildes, off_t offset, int whence) diff --git a/libexec/ld.so/util.h b/libexec/ld.so/util.h index b2368ef54f3..45115aa7cce 100644 --- a/libexec/ld.so/util.h +++ b/libexec/ld.so/util.h @@ -1,4 +1,4 @@ -/* $OpenBSD: util.h,v 1.22 2012/08/07 17:47:06 matthew Exp $ */ +/* $OpenBSD: util.h,v 1.23 2013/04/05 12:58:03 kurt Exp $ */ /* * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> @@ -31,11 +31,14 @@ #ifndef __DL_UTIL_H__ #define __DL_UTIL_H__ +#include <sys/utsname.h> #include <stdarg.h> void *_dl_malloc(const size_t size); void _dl_free(void *); char *_dl_strdup(const char *); +size_t _dl_strlen(const char *); +size_t _dl_strlcat(char *dst, const char *src, size_t siz); void _dl_printf(const char *fmt, ...); void _dl_vprintf(const char *fmt, va_list ap); void _dl_fdprintf(int, const char *fmt, ...); @@ -43,6 +46,9 @@ void _dl_show_objects(void); void _dl_randombuf(void *, size_t); unsigned int _dl_random(void); ssize_t _dl_write(int fd, const char* buf, size_t len); +char * _dl_dirname(const char *path); +char *_dl_realpath(const char *path, char *resolved); +int _dl_uname(struct utsname *name); long _dl_strtol(const char *nptr, char **endptr, int base); @@ -87,16 +93,6 @@ _dl_bcopy(const void *src, void *dest, int size) pdest[i] = psrc[i]; } -static inline int -_dl_strlen(const char *str) -{ - const char *s; - - for (s = str; *s; ++s) - ; - return (s - str); -} - static inline size_t _dl_strlcpy(char *dst, const char *src, size_t siz) { @@ -189,4 +185,10 @@ _dl_strstr(const char *s, const char *find) return ((char *)s); } +static inline int +_dl_isalnum(const char c) +{ + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); +} + #endif /*__DL_UTIL_H__*/ |