summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-03-12 12:15:47 +0000
committerkib <kib@FreeBSD.org>2012-03-12 12:15:47 +0000
commit4f080c8f731c78d2241481894214dbdcced51b11 (patch)
treef6f41526ae91d93a09f5bd0db36043d947e86893 /libexec/rtld-elf/rtld.c
parente35bb21f2cb0a6137642086ccd777ce4a652da39 (diff)
downloadFreeBSD-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/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c40
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();
+}
OpenPOWER on IntegriCloud