diff --git a/libexec/rtld-elf/arm/reloc.c b/libexec/rtld-elf/arm/reloc.c --- a/libexec/rtld-elf/arm/reloc.c +++ b/libexec/rtld-elf/arm/reloc.c @@ -16,7 +16,7 @@ #include "debug.h" #include "rtld.h" -#include "paths.h" +#include "rtld_paths.h" #ifdef __ARM_FP /* diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c --- a/libexec/rtld-elf/libmap.c +++ b/libexec/rtld-elf/libmap.c @@ -16,7 +16,7 @@ #include "debug.h" #include "rtld.h" #include "libmap.h" -#include "paths.h" +#include "rtld_paths.h" #include "rtld_libc.h" TAILQ_HEAD(lm_list, lm); diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1 --- a/libexec/rtld-elf/rtld.1 +++ b/libexec/rtld-elf/rtld.1 @@ -330,6 +330,7 @@ .Bd -ragged -offset indent .Pa /libexec/ld-elf.so.1 .Op Fl b Ar exe +.Op Fl d .Op Fl f Ar fd .Op Fl p .Op Fl u @@ -352,6 +353,8 @@ is only used to provide the .Va argv[0] value to the program. +.It Fl d +Turn off the emulation of the binary execute permission. .It Fl f Ar fd File descriptor .Ar fd @@ -403,6 +406,9 @@ and is naturally prone to race conditions. Environments which rely on such restrictions are weak and breakable on their own. +It can be turned off with the +.Fl d +option. .Sh VERSIONING Newer .Nm diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -63,7 +63,7 @@ #include "debug.h" #include "rtld.h" #include "libmap.h" -#include "paths.h" +#include "rtld_paths.h" #include "rtld_tls.h" #include "rtld_printf.h" #include "rtld_malloc.h" @@ -140,7 +140,7 @@ static int open_binary_fd(const char *argv0, bool search_in_path, const char **binpath_res); static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp, - const char **argv0); + const char **argv0, bool *dir_ignore); static int parse_integer(const char *); static void *path_enumerate(const char *, path_enum_proc, const char *, void *); static void print_usage(const char *argv0); @@ -503,7 +503,7 @@ #ifdef __powerpc__ int old_auxv_format = 1; #endif - bool dir_enable, direct_exec, explicit_fd, search_in_path; + bool dir_enable, dir_ignore, direct_exec, explicit_fd, search_in_path; /* * On entry, the dynamic linker itself has not been relocated yet. @@ -589,7 +589,8 @@ dbg("opening main program in direct exec mode"); if (argc >= 2) { - rtld_argc = parse_args(argv, argc, &search_in_path, &fd, &argv0); + rtld_argc = parse_args(argv, argc, &search_in_path, &fd, + &argv0, &dir_ignore); explicit_fd = (fd != -1); binpath = NULL; if (!explicit_fd) @@ -621,7 +622,7 @@ } else if ((st.st_mode & S_IXOTH) != 0) { dir_enable = true; } - if (!dir_enable) { + if (!dir_enable && !dir_ignore) { _rtld_error("No execute permission for binary %s", argv0); rtld_die(); @@ -5842,7 +5843,7 @@ */ static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp, - const char **argv0) + const char **argv0, bool *dir_ignore) { const char *arg; char machine[64]; @@ -5854,6 +5855,7 @@ dbg("Parsing command-line arguments"); *use_pathp = false; *fdp = -1; + *dir_ignore = false; seen_b = seen_f = false; for (i = 1; i < argc; i++ ) { @@ -5890,6 +5892,9 @@ *argv0 = argv[i]; seen_b = true; break; + } else if (opt == 'd') { + *dir_ignore = true; + break; } else if (opt == 'f') { if (seen_b) { _rtld_error("Both -b and -f specified"); @@ -5988,11 +5993,12 @@ { rtld_printf( - "Usage: %s [-h] [-b ] [-f ] [-p] [--] []\n" + "Usage: %s [-h] [-b ] [-d] [-f ] [-p] [--] []\n" "\n" "Options:\n" " -h Display this help message\n" " -b Execute instead of , arg0 is \n" + " -d Ignore lack of exec permissions for the binary\n" " -f Execute instead of searching for \n" " -p Search in PATH for named binary\n" " -u Ignore LD_ environment variables\n" diff --git a/libexec/rtld-elf/rtld_malloc.c b/libexec/rtld-elf/rtld_malloc.c --- a/libexec/rtld-elf/rtld_malloc.c +++ b/libexec/rtld-elf/rtld_malloc.c @@ -55,7 +55,7 @@ #include #include "rtld.h" #include "rtld_printf.h" -#include "paths.h" +#include "rtld_paths.h" /* * Pre-allocate mmap'ed pages diff --git a/libexec/rtld-elf/paths.h b/libexec/rtld-elf/rtld_paths.h rename from libexec/rtld-elf/paths.h rename to libexec/rtld-elf/rtld_paths.h --- a/libexec/rtld-elf/paths.h +++ b/libexec/rtld-elf/rtld_paths.h @@ -26,15 +26,19 @@ * $FreeBSD$ */ -#ifndef PATHS_H -#define PATHS_H +#ifndef _RTLD_PATHS_H +#define _RTLD_PATHS_H #undef _PATH_ELF_HINTS +#ifndef _COMPAT32_BASENAME_RTLD +#define _COMPAT32_BASENAME_RTLD "ld-elf32.so.1" +#endif + #ifdef COMPAT_32BIT #define _PATH_ELF_HINTS "/var/run/ld-elf32.so.hints" #define _PATH_LIBMAP_CONF "/etc/libmap32.conf" -#define _BASENAME_RTLD "ld-elf32.so.1" +#define _BASENAME_RTLD _COMPAT32_BASENAME_RTLD #define STANDARD_LIBRARY_PATH "/lib32:/usr/lib32" #define LD_ "LD_32_" #endif @@ -55,6 +59,10 @@ #define _PATH_RTLD "/libexec/" _BASENAME_RTLD #endif +#ifndef _COMPAT32_PATH_RTLD +#define _COMPAT32_PATH_RTLD "/libexec/" _COMPAT32_BASENAME_RTLD +#endif + #ifndef STANDARD_LIBRARY_PATH #define STANDARD_LIBRARY_PATH "/lib/casper:/lib:/usr/lib" #endif @@ -69,10 +77,12 @@ #define SOFT_STANDARD_LIBRARY_PATH "/usr/libsoft" #define LD_SOFT_ "LD_SOFT_" +#ifdef IN_RTLD extern const char *ld_elf_hints_default; extern const char *ld_path_libmap_conf; extern const char *ld_path_rtld; extern const char *ld_standard_library_path; extern const char *ld_env_prefix; +#endif -#endif /* PATHS_H */ +#endif /* _RTLD_PATHS_H */ diff --git a/usr.bin/ldd/Makefile b/usr.bin/ldd/Makefile --- a/usr.bin/ldd/Makefile +++ b/usr.bin/ldd/Makefile @@ -3,6 +3,7 @@ PROG?= ldd SRCS= ldd.c +CFLAGS+= -I${SRCTOP}/libexec/rtld-elf LIBADD= elf .include diff --git a/usr.bin/ldd/ldd.c b/usr.bin/ldd/ldd.c --- a/usr.bin/ldd/ldd.c +++ b/usr.bin/ldd/ldd.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,8 @@ main(int argc, char *argv[]) { char *fmt1, *fmt2; - int rval, c, aflag; + const char *rtld; + int aflag, c, fd, rval, status, is_shlib, rv, type; aflag = 0; fmt1 = fmt2 = NULL; @@ -167,8 +169,6 @@ rval = 0; for (; argc > 0; argc--, argv++) { - int fd, status, is_shlib, rv, type; - if ((fd = open(*argv, O_RDONLY, 0)) < 0) { warn("%s", *argv); rval |= 1; @@ -236,15 +236,23 @@ if (is_shlib == 0) { execl(*argv, *argv, (char *)NULL); warn("%s", *argv); - } else { + } else if (fmt1 == NULL && fmt2 == NULL) { dlopen(*argv, RTLD_TRACE); warnx("%s: %s", *argv, dlerror()); + } else { + rtld = _PATH_RTLD; +#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) + if (type == TYPE_ELF32) + rtld = _COMPAT32_PATH_RTLD; +#endif + execl(rtld, rtld, "-d", "--", + *argv, (char *)NULL); } _exit(1); } } - return rval; + return (rval); } static void