Changeset View
Changeset View
Standalone View
Standalone View
head/libexec/rtld-elf/rtld.c
Show First 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | |||||
static void objlist_call_init(Objlist *, RtldLockState *); | static void objlist_call_init(Objlist *, RtldLockState *); | ||||
static void objlist_clear(Objlist *); | static void objlist_clear(Objlist *); | ||||
static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *); | static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *); | ||||
static void objlist_init(Objlist *); | static void objlist_init(Objlist *); | ||||
static void objlist_push_head(Objlist *, Obj_Entry *); | static void objlist_push_head(Objlist *, Obj_Entry *); | ||||
static void objlist_push_tail(Objlist *, Obj_Entry *); | static void objlist_push_tail(Objlist *, Obj_Entry *); | ||||
static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *); | static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *); | ||||
static void objlist_remove(Objlist *, Obj_Entry *); | static void objlist_remove(Objlist *, Obj_Entry *); | ||||
static int open_binary_fd(const char *argv0, bool search_in_path); | 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); | static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp); | ||||
static int parse_integer(const char *); | static int parse_integer(const char *); | ||||
static void *path_enumerate(const char *, path_enum_proc, const char *, void *); | static void *path_enumerate(const char *, path_enum_proc, const char *, void *); | ||||
static void print_usage(const char *argv0); | static void print_usage(const char *argv0); | ||||
static void release_object(Obj_Entry *); | static void release_object(Obj_Entry *); | ||||
static int relocate_object_dag(Obj_Entry *root, bool bind_now, | static int relocate_object_dag(Obj_Entry *root, bool bind_now, | ||||
Obj_Entry *rtldobj, int flags, RtldLockState *lockstate); | Obj_Entry *rtldobj, int flags, RtldLockState *lockstate); | ||||
static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, | static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, | ||||
▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) | ||||
Objlist_Entry *entry; | Objlist_Entry *entry; | ||||
Obj_Entry *last_interposer, *obj, *preload_tail; | Obj_Entry *last_interposer, *obj, *preload_tail; | ||||
const Elf_Phdr *phdr; | const Elf_Phdr *phdr; | ||||
Objlist initlist; | Objlist initlist; | ||||
RtldLockState lockstate; | RtldLockState lockstate; | ||||
struct stat st; | struct stat st; | ||||
Elf_Addr *argcp; | Elf_Addr *argcp; | ||||
char **argv, **env, **envp, *kexecpath, *library_path_rpath; | char **argv, **env, **envp, *kexecpath, *library_path_rpath; | ||||
const char *argv0; | const char *argv0, *binpath; | ||||
caddr_t imgentry; | caddr_t imgentry; | ||||
char buf[MAXPATHLEN]; | char buf[MAXPATHLEN]; | ||||
int argc, fd, i, phnum, rtld_argc; | int argc, fd, i, phnum, rtld_argc; | ||||
#ifdef __powerpc__ | #ifdef __powerpc__ | ||||
int old_auxv_format = 1; | int old_auxv_format = 1; | ||||
#endif | #endif | ||||
bool dir_enable, explicit_fd, search_in_path; | bool dir_enable, explicit_fd, search_in_path; | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | _rtld_error("Tainted process refusing to run binary %s", | ||||
argv0); | argv0); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
dbg("opening main program in direct exec mode"); | dbg("opening main program in direct exec mode"); | ||||
if (argc >= 2) { | if (argc >= 2) { | ||||
rtld_argc = parse_args(argv, argc, &search_in_path, &fd); | rtld_argc = parse_args(argv, argc, &search_in_path, &fd); | ||||
argv0 = argv[rtld_argc]; | argv0 = argv[rtld_argc]; | ||||
explicit_fd = (fd != -1); | explicit_fd = (fd != -1); | ||||
binpath = NULL; | |||||
if (!explicit_fd) | if (!explicit_fd) | ||||
fd = open_binary_fd(argv0, search_in_path); | fd = open_binary_fd(argv0, search_in_path, &binpath); | ||||
if (fstat(fd, &st) == -1) { | if (fstat(fd, &st) == -1) { | ||||
_rtld_error("Failed to fstat FD %d (%s): %s", fd, | _rtld_error("Failed to fstat FD %d (%s): %s", fd, | ||||
explicit_fd ? "user-provided descriptor" : argv0, | explicit_fd ? "user-provided descriptor" : argv0, | ||||
rtld_strerror(errno)); | rtld_strerror(errno)); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
/* | /* | ||||
Show All 36 Lines | if (phdr == obj_rtld.phdr) { | ||||
*argcp -= rtld_argc; | *argcp -= rtld_argc; | ||||
environ = env = envp = argv + main_argc + 1; | environ = env = envp = argv + main_argc + 1; | ||||
do { | do { | ||||
*envp = *(envp + rtld_argc); | *envp = *(envp + rtld_argc); | ||||
envp++; | envp++; | ||||
} while (*envp != NULL); | } while (*envp != NULL); | ||||
aux = auxp = (Elf_Auxinfo *)envp; | aux = auxp = (Elf_Auxinfo *)envp; | ||||
auxpf = (Elf_Auxinfo *)(envp + rtld_argc); | auxpf = (Elf_Auxinfo *)(envp + rtld_argc); | ||||
/* XXXKIB insert place for AT_EXECPATH if not present */ | |||||
for (;; auxp++, auxpf++) { | for (;; auxp++, auxpf++) { | ||||
*auxp = *auxpf; | *auxp = *auxpf; | ||||
if (auxp->a_type == AT_NULL) | if (auxp->a_type == AT_NULL) | ||||
break; | break; | ||||
} | } | ||||
/* Since the auxiliary vector has moved, redigest it. */ | /* Since the auxiliary vector has moved, redigest it. */ | ||||
for (i = 0; i < AT_COUNT; i++) | for (i = 0; i < AT_COUNT; i++) | ||||
aux_info[i] = NULL; | aux_info[i] = NULL; | ||||
for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { | for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { | ||||
if (auxp->a_type < AT_COUNT) | if (auxp->a_type < AT_COUNT) | ||||
aux_info[auxp->a_type] = auxp; | aux_info[auxp->a_type] = auxp; | ||||
} | } | ||||
/* Point AT_EXECPATH auxv and aux_info to the binary path. */ | |||||
if (binpath == NULL) { | |||||
aux_info[AT_EXECPATH] = NULL; | |||||
} else { | } else { | ||||
if (aux_info[AT_EXECPATH] == NULL) { | |||||
aux_info[AT_EXECPATH] = xmalloc(sizeof(Elf_Auxinfo)); | |||||
aux_info[AT_EXECPATH]->a_type = AT_EXECPATH; | |||||
} | |||||
aux_info[AT_EXECPATH]->a_un.a_ptr = __DECONST(void *, | |||||
binpath); | |||||
} | |||||
} else { | |||||
_rtld_error("No binary"); | _rtld_error("No binary"); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
ld_bind_now = getenv(_LD("BIND_NOW")); | ld_bind_now = getenv(_LD("BIND_NOW")); | ||||
▲ Show 20 Lines • Show All 4,947 Lines • ▼ Show 20 Lines | symlook_init_from_req(SymLook *dst, const SymLook *src) | ||||
dst->ventry = src->ventry; | dst->ventry = src->ventry; | ||||
dst->flags = src->flags; | dst->flags = src->flags; | ||||
dst->defobj_out = NULL; | dst->defobj_out = NULL; | ||||
dst->sym_out = NULL; | dst->sym_out = NULL; | ||||
dst->lockstate = src->lockstate; | dst->lockstate = src->lockstate; | ||||
} | } | ||||
static int | static int | ||||
open_binary_fd(const char *argv0, bool search_in_path) | open_binary_fd(const char *argv0, bool search_in_path, | ||||
const char **binpath_res) | |||||
{ | { | ||||
char *pathenv, *pe, binpath[PATH_MAX]; | char *pathenv, *pe, *binpath; | ||||
int fd; | int fd; | ||||
if (search_in_path && strchr(argv0, '/') == NULL) { | if (search_in_path && strchr(argv0, '/') == NULL) { | ||||
binpath = xmalloc(PATH_MAX); | |||||
pathenv = getenv("PATH"); | pathenv = getenv("PATH"); | ||||
if (pathenv == NULL) { | if (pathenv == NULL) { | ||||
_rtld_error("-p and no PATH environment variable"); | _rtld_error("-p and no PATH environment variable"); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
pathenv = strdup(pathenv); | pathenv = strdup(pathenv); | ||||
if (pathenv == NULL) { | if (pathenv == NULL) { | ||||
_rtld_error("Cannot allocate memory"); | _rtld_error("Cannot allocate memory"); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
fd = -1; | fd = -1; | ||||
errno = ENOENT; | errno = ENOENT; | ||||
while ((pe = strsep(&pathenv, ":")) != NULL) { | while ((pe = strsep(&pathenv, ":")) != NULL) { | ||||
if (strlcpy(binpath, pe, sizeof(binpath)) >= | if (strlcpy(binpath, pe, sizeof(binpath)) >= | ||||
sizeof(binpath)) | sizeof(binpath)) | ||||
continue; | continue; | ||||
if (binpath[0] != '\0' && | if (binpath[0] != '\0' && | ||||
strlcat(binpath, "/", sizeof(binpath)) >= | strlcat(binpath, "/", sizeof(binpath)) >= | ||||
sizeof(binpath)) | sizeof(binpath)) | ||||
continue; | continue; | ||||
if (strlcat(binpath, argv0, sizeof(binpath)) >= | if (strlcat(binpath, argv0, sizeof(binpath)) >= | ||||
sizeof(binpath)) | sizeof(binpath)) | ||||
continue; | continue; | ||||
fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY); | fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY); | ||||
if (fd != -1 || errno != ENOENT) | if (fd != -1 || errno != ENOENT) { | ||||
*binpath_res = binpath; | |||||
break; | break; | ||||
} | } | ||||
} | |||||
free(pathenv); | free(pathenv); | ||||
} else { | } else { | ||||
fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY); | fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY); | ||||
*binpath_res = argv0; | |||||
} | } | ||||
/* XXXKIB Use getcwd() to resolve relative binpath to absolute. */ | |||||
if (fd == -1) { | if (fd == -1) { | ||||
_rtld_error("Cannot open %s: %s", argv0, rtld_strerror(errno)); | _rtld_error("Cannot open %s: %s", argv0, rtld_strerror(errno)); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
return (fd); | return (fd); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 197 Lines • Show Last 20 Lines |