DF-5713 / fix.diff
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 |