svn commit: r332940 - head/lib/libc/secure

Konstantin Belousov kib at FreeBSD.org
Tue Apr 24 15:59:40 UTC 2018


Author: kib
Date: Tue Apr 24 15:59:39 2018
New Revision: 332940
URL: https://svnweb.freebsd.org/changeset/base/332940

Log:
  Carefully update stack guard bytes inside __guard_setup().
  
  This is necessary to make sure that functions that can have stack
  protection are not used to update the stack guard. If not, the stack
  guard check would fail when it shouldn't.
  
  guard_setup() calls elf_aux_info(), which, in turn, calls memcpy() to
  update stack_chk_guard.  If either elf_aux_info() or memcpy() have
  stack protection enabled, __stack_chk_guard will be modified before
  returning from them, causing the stack protection check to fail.
  
  This change uses a temporary buffer to delay changing
  __stack_chk_guard until elf_aux_info() returns.
  
  Submitted by:	Luis Pires
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D15173

Modified:
  head/lib/libc/secure/stack_protector.c

Modified: head/lib/libc/secure/stack_protector.c
==============================================================================
--- head/lib/libc/secure/stack_protector.c	Tue Apr 24 15:04:07 2018	(r332939)
+++ head/lib/libc/secure/stack_protector.c	Tue Apr 24 15:59:39 2018	(r332940)
@@ -54,15 +54,27 @@ static void
 __guard_setup(void)
 {
 	static const int mib[2] = { CTL_KERN, KERN_ARND };
+	volatile long tmp_stack_chk_guard[nitems(__stack_chk_guard)];
 	size_t len;
-	int error;
+	int error, idx;
 
 	if (__stack_chk_guard[0] != 0)
 		return;
-	error = _elf_aux_info(AT_CANARY, __stack_chk_guard,
-	    sizeof(__stack_chk_guard));
-	if (error == 0 && __stack_chk_guard[0] != 0)
+	/*
+	 * Avoid using functions which might have stack protection
+	 * enabled, to update the __stack_chk_guard.  First fetch the
+	 * data into a temporal array, then do manual volatile copy to
+	 * not allow optimizer to call memcpy() behind us.
+	 */
+	error = _elf_aux_info(AT_CANARY, (void *)tmp_stack_chk_guard,
+	    sizeof(tmp_stack_chk_guard));
+	if (error == 0 && tmp_stack_chk_guard[0] != 0) {
+		for (idx = 0; idx < nitems(__stack_chk_guard); idx++) {
+			__stack_chk_guard[idx] = tmp_stack_chk_guard[idx];
+			tmp_stack_chk_guard[idx] = 0;
+		}
 		return;
+	}
 
 	len = sizeof(__stack_chk_guard);
 	if (__sysctl(mib, nitems(mib), __stack_chk_guard, &len, NULL, 0) ==


More information about the svn-src-all mailing list