diff options
author | kib <kib@FreeBSD.org> | 2012-03-12 12:15:47 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-03-12 12:15:47 +0000 |
commit | 4f080c8f731c78d2241481894214dbdcced51b11 (patch) | |
tree | f6f41526ae91d93a09f5bd0db36043d947e86893 /libexec | |
parent | e35bb21f2cb0a6137642086ccd777ce4a652da39 (diff) | |
download | FreeBSD-src-4f080c8f731c78d2241481894214dbdcced51b11.zip FreeBSD-src-4f080c8f731c78d2241481894214dbdcced51b11.tar.gz |
Rtld on diet part 1:
Provide rtld-private implementations of __stack_chk_guard,
__stack_chk_fail() and __chk_fail() symbols, to be used by functions
linked from libc_pic.a. This avoids use of libc stack_protector.c,
which pulls in syslog(3) and stdio as dependency.
Also, do initialize rtld-private copy __stack_chk_guard, previously
libc-provided one was not initialized, since we do not call rtld
object _init() methods.
Reviewed by: kan
MFC after: 3 weeks
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 98391d6..1ca5ba0 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -196,6 +196,8 @@ extern Elf_Dyn _DYNAMIC; int osreldate, pagesize; +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 max_stack_flags; @@ -311,6 +313,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) Obj_Entry **preload_tail; Objlist initlist; RtldLockState lockstate; + int mib[2]; + size_t len; /* * On entry, the dynamic linker itself has not been relocated yet. @@ -346,6 +350,26 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) main_argc = argc; main_argv = argv; + if (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(); ld_bind_now = getenv(LD_ "BIND_NOW"); @@ -4313,3 +4337,19 @@ void __pthread_cxa_finalize(struct dl_phdr_info *a) { } + +void +__stack_chk_fail(void) +{ + + _rtld_error("stack overflow detected; terminated"); + die(); +} + +void +__chk_fail(void) +{ + + _rtld_error("buffer overflow detected; terminated"); + die(); +} |