Changeset View
Changeset View
Standalone View
Standalone View
head/libexec/rtld-elf/rtld.c
Show First 20 Lines • Show All 232 Lines • ▼ Show 20 Lines | |||||
int _rtld_addr_phdr(const void *, struct dl_phdr_info *) __exported; | int _rtld_addr_phdr(const void *, struct dl_phdr_info *) __exported; | ||||
int _rtld_get_stack_prot(void) __exported; | int _rtld_get_stack_prot(void) __exported; | ||||
int _rtld_is_dlopened(void *) __exported; | int _rtld_is_dlopened(void *) __exported; | ||||
void _rtld_error(const char *, ...) __exported; | void _rtld_error(const char *, ...) __exported; | ||||
int npagesizes, osreldate; | int npagesizes, osreldate; | ||||
size_t *pagesizes; | size_t *pagesizes; | ||||
long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | |||||
static int stack_prot = PROT_READ | PROT_WRITE | RTLD_DEFAULT_STACK_EXEC; | static int stack_prot = PROT_READ | PROT_WRITE | RTLD_DEFAULT_STACK_EXEC; | ||||
static int max_stack_flags; | static int max_stack_flags; | ||||
/* | /* | ||||
* Global declarations normally provided by crt1. The dynamic linker is | * Global declarations normally provided by crt1. The dynamic linker is | ||||
* not built with crt1, so we have to provide them ourselves. | * not built with crt1, so we have to provide them ourselves. | ||||
*/ | */ | ||||
char *__progname; | char *__progname; | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) | ||||
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, *argv0, **env, **envp, *kexecpath, *library_path_rpath; | char **argv, *argv0, **env, **envp, *kexecpath, *library_path_rpath; | ||||
caddr_t imgentry; | caddr_t imgentry; | ||||
char buf[MAXPATHLEN]; | char buf[MAXPATHLEN]; | ||||
int argc, fd, i, mib[2], phnum, rtld_argc; | int argc, fd, i, phnum, rtld_argc; | ||||
size_t len; | |||||
bool dir_enable, explicit_fd, search_in_path; | bool dir_enable, explicit_fd, search_in_path; | ||||
/* | /* | ||||
* On entry, the dynamic linker itself has not been relocated yet. | * On entry, the dynamic linker itself has not been relocated yet. | ||||
* Be very careful not to reference any global data until after | * Be very careful not to reference any global data until after | ||||
* init_rtld has returned. It is OK to reference file-scope statics | * init_rtld has returned. It is OK to reference file-scope statics | ||||
* and string constants, and to call static and global functions. | * and string constants, and to call static and global functions. | ||||
*/ | */ | ||||
Show All 21 Lines | if (auxp->a_type < AT_COUNT) | ||||
init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info); | init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info); | ||||
__progname = obj_rtld.path; | __progname = obj_rtld.path; | ||||
argv0 = argv[0] != NULL ? argv[0] : "(null)"; | argv0 = argv[0] != NULL ? argv[0] : "(null)"; | ||||
environ = env; | environ = env; | ||||
main_argc = argc; | main_argc = argc; | ||||
main_argv = argv; | main_argv = argv; | ||||
if (aux_info[AT_CANARY] != NULL && | |||||
aux_info[AT_CANARY]->a_un.a_ptr != NULL) { | |||||
i = aux_info[AT_CANARYLEN]->a_un.a_val; | |||||
if (i > sizeof(__stack_chk_guard)) | |||||
i = sizeof(__stack_chk_guard); | |||||
memcpy(__stack_chk_guard, aux_info[AT_CANARY]->a_un.a_ptr, i); | |||||
} else { | |||||
mib[0] = CTL_KERN; | |||||
mib[1] = KERN_ARND; | |||||
len = sizeof(__stack_chk_guard); | |||||
if (sysctl(mib, 2, __stack_chk_guard, &len, NULL, 0) == -1 || | |||||
len != sizeof(__stack_chk_guard)) { | |||||
/* If sysctl was unsuccessful, use the "terminator canary". */ | |||||
((unsigned char *)(void *)__stack_chk_guard)[0] = 0; | |||||
((unsigned char *)(void *)__stack_chk_guard)[1] = 0; | |||||
((unsigned char *)(void *)__stack_chk_guard)[2] = '\n'; | |||||
((unsigned char *)(void *)__stack_chk_guard)[3] = 255; | |||||
} | |||||
} | |||||
trust = !issetugid(); | trust = !issetugid(); | ||||
md_abi_variant_hook(aux_info); | md_abi_variant_hook(aux_info); | ||||
fd = -1; | fd = -1; | ||||
if (aux_info[AT_EXECFD] != NULL) { | if (aux_info[AT_EXECFD] != NULL) { | ||||
fd = aux_info[AT_EXECFD]->a_un.a_val; | fd = aux_info[AT_EXECFD]->a_un.a_val; | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 5,099 Lines • ▼ Show 20 Lines | |||||
int _thread_autoinit_dummy_decl = 1; | int _thread_autoinit_dummy_decl = 1; | ||||
/* | /* | ||||
* No unresolved symbols for rtld. | * No unresolved symbols for rtld. | ||||
*/ | */ | ||||
void | void | ||||
__pthread_cxa_finalize(struct dl_phdr_info *a) | __pthread_cxa_finalize(struct dl_phdr_info *a) | ||||
{ | { | ||||
} | |||||
void | |||||
__stack_chk_fail(void) | |||||
{ | |||||
_rtld_error("stack overflow detected; terminated"); | |||||
rtld_die(); | |||||
} | |||||
__weak_reference(__stack_chk_fail, __stack_chk_fail_local); | |||||
void | |||||
__chk_fail(void) | |||||
{ | |||||
_rtld_error("buffer overflow detected; terminated"); | |||||
rtld_die(); | |||||
} | } | ||||
const char * | const char * | ||||
rtld_strerror(int errnum) | rtld_strerror(int errnum) | ||||
{ | { | ||||
if (errnum < 0 || errnum >= sys_nerr) | if (errnum < 0 || errnum >= sys_nerr) | ||||
return ("Unknown error"); | return ("Unknown error"); | ||||
return (sys_errlist[errnum]); | return (sys_errlist[errnum]); | ||||
} | } |