From ada7b9dc1904d1cd7c7c0176f0b322d598e337b0 Mon Sep 17 00:00:00 2001 From: kib Date: Mon, 12 Mar 2012 12:15:47 +0000 Subject: [PATCH 135/175] 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 git-svn-id: http://svn.freebsd.org/base/head@232861 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f (cherry picked from commit 019c839575bcaf256045f05abfd513a1d5645eeb) Signed-off-by: Xin Li --- libexec/rtld-elf/rtld.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) 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(); +} -- 1.7.9.4