Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:07:50 -0000
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r346292 - in head: . sys/kern
Message-ID:  <201904161847.x3GIlKir077013@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Tue Apr 16 18:47:20 2019
New Revision: 346292
URL: https://svnweb.freebsd.org/changeset/base/346292

Log:
  stack_protector: Add tunable to bypass random cookies
  
  This is a stopgap measure to unbreak installer/VM/embedded boot issues
  introduced (or at least exposed by) in r346250.
  
  Add the new tunable, "security.stack_protect.permit_nonrandom_cookies," in
  order to continue boot with insecure non-random stack cookies if the random
  device is unavailable.
  
  For now, enable it by default.  This is NOT safe.  It will be disabled by
  default in a future revision.
  
  There is follow-on work planned to use fast random sources (e.g., RDRAND on
  x86 and DARN on Power) to seed when the early entropy file cannot be
  provided, for whatever reason.  Please see D19928.
  
  Some better hacks may be used to make the non-random __stack_chk_guard
  slightly less predictable (from delphij@ and mjg@); those suggestions are
  left for a future revision.  I think it may also be plausible to move stack
  guard initialization far later in the boot process; potentially it could be
  moved all the way to just before userspace is started.
  
  Reported by:	many
  Reviewed by:	delphij, emaste, imp (all w/ caveat: this is a stopgap fix)
  Security:	yes
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D19927

Modified:
  head/UPDATING
  head/sys/kern/stack_protector.c

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Tue Apr 16 18:32:07 2019	(r346291)
+++ head/UPDATING	Tue Apr 16 18:47:20 2019	(r346292)
@@ -32,6 +32,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
 
 20190416:
+	The tunable "security.stack_protect.permit_nonrandom_cookies" may be
+	set to a non-zero value to boot systems that do not provide early
+	entropy.  Otherwise, such systems may see the panic message:
+	"cannot initialize stack cookies because random device is not yet
+	seeded."
+
+20190416:
 	The loadable random module KPI has changed; the random_infra_init()
 	routine now requires a 3rd function pointer for a bool (*)(void)
 	method that returns true if the random device is seeded (and

Modified: head/sys/kern/stack_protector.c
==============================================================================
--- head/sys/kern/stack_protector.c	Tue Apr 16 18:32:07 2019	(r346291)
+++ head/sys/kern/stack_protector.c	Tue Apr 16 18:47:20 2019	(r346292)
@@ -4,12 +4,28 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/random.h>
+#include <sys/sysctl.h>
 #include <sys/systm.h>
 #include <sys/libkern.h>
 
 long __stack_chk_guard[8] = {};
 void __stack_chk_fail(void);
 
+/*
+ * XXX This default is unsafe!!!  We intend to change it after resolving issues
+ * with early entropy in the installer; some kinds of systems that do not use
+ * loader(8), such as riscv, aarch64, and power; and perhaps others that I am
+ * forgetting off the top of my head.
+ */
+static bool permit_nonrandom_cookies = true;
+
+SYSCTL_NODE(_security, OID_AUTO, stack_protect, CTLFLAG_RW, 0,
+    "-fstack-protect support");
+SYSCTL_BOOL(_security_stack_protect, OID_AUTO, permit_nonrandom_cookies,
+    CTLFLAG_RDTUN, &permit_nonrandom_cookies, 0,
+    "Allow stack guard to be used without real random cookies");
+
 void
 __stack_chk_fail(void)
 {
@@ -23,8 +39,37 @@ __stack_chk_init(void *dummy __unused)
 	size_t i;
 	long guard[nitems(__stack_chk_guard)];
 
-	arc4rand(guard, sizeof(guard), 0);
-	for (i = 0; i < nitems(guard); i++)
-		__stack_chk_guard[i] = guard[i];
+	if (is_random_seeded()) {
+		arc4rand(guard, sizeof(guard), 0);
+		for (i = 0; i < nitems(guard); i++)
+			__stack_chk_guard[i] = guard[i];
+		return;
+	}
+
+	if (permit_nonrandom_cookies) {
+		printf("%s: WARNING: Initializing stack protection with "
+		    "non-random cookies!\n", __func__);
+		printf("%s: WARNING: This severely limits the benefit of "
+		    "-fstack-protector!\n", __func__);
+
+		/*
+		 * The emperor is naked, but I rolled some dice and at least
+		 * these values aren't zero.
+		 */
+		__stack_chk_guard[0] = (long)0xe7318d5959af899full;
+		__stack_chk_guard[1] = (long)0x35a9481c089348bfull;
+		__stack_chk_guard[2] = (long)0xde657fdc04117255ull;
+		__stack_chk_guard[3] = (long)0x0dd44c61c22e4a6bull;
+		__stack_chk_guard[4] = (long)0x0a5869a354edb0a5ull;
+		__stack_chk_guard[5] = (long)0x05cebfed255b5232ull;
+		__stack_chk_guard[6] = (long)0x270ffac137c4c72full;
+		__stack_chk_guard[7] = (long)0xd8141a789bad478dull;
+		_Static_assert(nitems(__stack_chk_guard) == 8,
+		    "__stack_chk_guard doesn't have 8 items");
+		return;
+	}
+
+	panic("%s: cannot initialize stack cookies because random device is "
+	    "not yet seeded", __func__);
 }
 SYSINIT(stack_chk, SI_SUB_RANDOM, SI_ORDER_ANY, __stack_chk_init, NULL);





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