DF-2798 / fix_validation.log
DF-2798 fix validation (fix.diff applied to guest /usr/src, kernel rebuilt:
make -j8 nativekernel KERNCONF=X86_64_GENERIC ; make installkernel
fixed kernel: DragonFly dfbsd 6.5-DEVELOPMENT #1: Tue Sep 1 12:02:52 UTC 2026)
=== A/B 1: kernel mode, KLD aoobfree.ko on FIXED kernel ===
baseline (stock #0 kernel, from panic.txt):
panic: assertion "blkno + count <= bl->bl_blocks" failed in alist_free at /usr/src/sys/kern/subr_alist.c:286
(INVARIANTS-only KKASSERT -- absent on production kernels, which is the bug)
fixed (#1 kernel, serial console):
aoobfree: creating own alist(100)
aoobfree: calling alist_free(bl,128,32) with bl_blocks=100 -- expect KKASSERT panic at :286
panic: alist_free: free 128+32 beyond limit of 100
Trace: alist_free+0xa9 <- aoobfree_modevent+0x8e <- module_register_init ...
The panic is now UNCONDITIONAL (present on production kernels) and fires at
the top of alist_free BEFORE any meta bit is poisoned. Intentional
fail-loud semantics, matching the file's existing unconditional panics
(alst_leaf_free "freeing free block", alst_meta_free "beyond limit").
=== A/B 2: standalone production-kernel emulation (-DNDEBUG) against PATCHED source ===
$ ./trigger_oobfree_fixed # baseline output in run.log
== T1 (silent full-cover OOB free -> out-of-domain alloc) ==
geometry: blocks=100 radix=512 skip=16 rootblks=17
after free-all: bl_free=100 root bitmap=0000007f
alist_free: free 128+32 beyond limit of 100
(process exits via panic(): exit 1 -- baseline continued silently:
"bl_free=132 (capacity=100!)", then handed out block 128)
VERDICT: fixed -- the silent production-kernel path is eliminated; the
meta bits can no longer be poisoned (bounds enforced before recursion);
the direct-allocation path additionally refuses spans beyond bl_blocks
(defense in depth), and bl_root is now allocated with M_ZERO.