diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2015-01-20 02:16:20 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2015-01-20 02:16:20 +0000 |
commit | 905ed6512d113cd69dd3ae060547ac92ad12ba06 (patch) | |
tree | 013641677b90ceae84aa6c382494a1817a092400 /libexec/ld.so/ldd | |
parent | 25ce9a50811f15a7fa1166f22cbb1247d4181b56 (diff) |
Add support for tracing libraries in static PIE binaries. rcrt does not
contain "LD_TRACE_LOADED_OBJECTS" support, so this gets done by calling
RTLD_TRACE directly.
ok guenther
Diffstat (limited to 'libexec/ld.so/ldd')
-rw-r--r-- | libexec/ld.so/ldd/ldd.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/libexec/ld.so/ldd/ldd.c b/libexec/ld.so/ldd/ldd.c index 127961be189..c1488cbf45a 100644 --- a/libexec/ld.so/ldd/ldd.c +++ b/libexec/ld.so/ldd/ldd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldd.c,v 1.18 2015/01/16 16:18:07 deraadt Exp $ */ +/* $OpenBSD: ldd.c,v 1.19 2015/01/20 02:16:19 deraadt Exp $ */ /* * Copyright (c) 2001 Artur Grabowski <art@openbsd.org> * All rights reserved. @@ -30,9 +30,11 @@ #include <err.h> #include <fcntl.h> #include <string.h> +#include <signal.h> #include <unistd.h> #include <limits.h> #include <dlfcn.h> +#include <errno.h> #include <sys/stat.h> #include <sys/mman.h> @@ -96,6 +98,7 @@ doit(char *name) Elf_Phdr *phdr; int fd, i, size, status, interp=0; char buf[PATH_MAX]; + struct stat st; void * dlhandle; if ((fd = open(name, O_RDONLY)) < 0) { @@ -103,6 +106,17 @@ doit(char *name) return 1; } + if (fstat(fd, &st) == -1) { + warn("%s", name); + close(fd); + return 1; + } + + if (!S_ISREG(st.st_mode)) { + warnx("%s: not an regular file", name); + close(fd); + return 1; + } if (read(fd, &ehdr, sizeof(ehdr)) < 0) { warn("read(%s)", name); close(fd); @@ -135,31 +149,34 @@ doit(char *name) } free(phdr); - if (ehdr.e_type == ET_DYN && !interp) { - printf("%s:\n", name); - if (realpath(name, buf) == NULL) { - warn("realpath(%s)", name); - return 1; - } - dlhandle = dlopen(buf, RTLD_TRACE); - if (dlhandle == NULL) { - printf("%s\n", dlerror()); - return 1; - } - return 0; - } - - if (i == ehdr.e_phnum) { - warnx("%s: not a dynamic executable", name); - return 1; - } - printf("%s:\n", name); fflush(stdout); switch (fork()) { case -1: err(1, "fork"); case 0: + if (ehdr.e_type == ET_DYN && !interp) { + if (realpath(name, buf) == NULL) { + printf("realpath(%s): %s", name, + strerror(errno)); + fflush(stdout); + _exit(1); + } + dlhandle = dlopen(buf, RTLD_TRACE); + if (dlhandle == NULL) { + printf("%s\n", dlerror()); + fflush(stdout); + _exit(1); + } + _exit(0); + } + + if (i == ehdr.e_phnum) { + printf("not a dynamic executable\n"); + fflush(stdout); + _exit(0); + } + execl(name, name, (char *)NULL); perror(name); _exit(1); @@ -169,6 +186,8 @@ doit(char *name) return 1; } if (WIFSIGNALED(status)) { + if (WTERMSIG(status) == SIGINT) + return 1; fprintf(stderr, "%s: signal %d\n", name, WTERMSIG(status)); return 1; |