⬢ DragonFlyBSD Kernel Audit
DF-5713 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/libkern/stack_protector.c b/sys/libkern/stack_protector.c
--- a/sys/libkern/stack_protector.c	2026-10-10 13:06:11.322446958 +0000
+++ b/sys/libkern/stack_protector.c	2026-10-10 13:06:19.398342702 +0000
@@ -26,10 +26,30 @@
 
 #include <sys/param.h>
 #include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/systm.h>
 #ifndef _KERNEL
 extern void panic(const char *, ...);
 #endif
 
+#ifdef _KERNEL
+/*
+ * Modern ABI (gcc >= 4.1, clang): -fstack-protector* emits references to
+ * __stack_chk_guard / __stack_chk_fail.  DragonFly never provided them,
+ * while kern.mk forced -fno-stack-protector, so the legacy machinery
+ * below was dead code guarding nothing -- and its value was the
+ * publicly-known compile-time constant 0x00000aff (DF-5713).
+ *
+ * __stack_chk_guard keeps the legacy constant as its pre-seed value so
+ * any early-boot use is no worse than the old __guard; it is reseeded
+ * from karc4random_buf() once per-CPU arc4 state exists
+ * (arc4_init_pcpu() runs no later than SI_BOOT2_FINISH_SMP = 0x1c80000,
+ * which precedes SI_SUB_DRIVERS = 0x2400000).
+ */
+unsigned long __stack_chk_guard = 0x00000affUL;
+#endif
+
 void __stack_smash_handler(char[], int);
 
 #if BYTE_ORDER == LITTLE_ENDIAN
@@ -38,6 +58,34 @@
 int __guard = 0xff0a0000;
 #endif
 
+#ifdef _KERNEL
+static void
+stack_chk_seed(void *dummy __unused)
+{
+	karc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard));
+	/*
+	 * Classic terminator property: NUL in the lowest byte so that
+	 * strcpy-style overflows stop inside the canary instead of
+	 * running past it into the saved frame.
+	 */
+	((unsigned char *)&__stack_chk_guard)[0] = 0;
+
+	/* Legacy propolice ABI (stand/boot consumers): real entropy too. */
+	karc4random_buf(&__guard, sizeof(__guard));
+}
+SYSINIT(stack_chk_seed, SI_SUB_DRIVERS, SI_ORDER_FIRST, stack_chk_seed, NULL);
+
+/*
+ * Modern failure path.  The compiler passes no context, so mirror the
+ * panic style of __stack_smash_handler().
+ */
+void
+__stack_chk_fail(void)
+{
+	panic("stack overflow detected (canary mismatch)");
+}
+#endif
+
 void 
 __stack_smash_handler(char func[], int damaged)
 {
diff --git a/sys/platform/pc64/conf/kern.mk b/sys/platform/pc64/conf/kern.mk
--- a/sys/platform/pc64/conf/kern.mk	2026-10-10 13:06:11.322446958 +0000
+++ b/sys/platform/pc64/conf/kern.mk	2026-10-10 13:06:19.398342702 +0000
@@ -4,7 +4,11 @@
 #
 # -fno-strict-aliasing required for -O2 compilation.
 #
-CFLAGS+=	-fno-stack-protector -fno-strict-aliasing
+# -fstack-protector-strong instruments kernel C functions with canary
+# checks against __stack_chk_guard (see libkern/stack_protector.c);
+# requires full kernel rebuild + boot validation before commit.
+#
+CFLAGS+=	-fstack-protector-strong -fno-strict-aliasing
 CFLAGS+=	-fno-strict-overflow
 CFLAGS+=	-fno-asynchronous-unwind-tables -fno-omit-frame-pointer