Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Mar 2012 12:15:47 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232861 - head/libexec/rtld-elf
Message-ID:  <201203121215.q2CCFlsZ061254@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Mar 12 12:15:47 2012
New Revision: 232861
URL: http://svn.freebsd.org/changeset/base/232861

Log:
  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

Modified:
  head/libexec/rtld-elf/rtld.c

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Mon Mar 12 11:56:57 2012	(r232860)
+++ head/libexec/rtld-elf/rtld.c	Mon Mar 12 12:15:47 2012	(r232861)
@@ -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_
     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_
     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();
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203121215.q2CCFlsZ061254>