DF-4986 / verdict.json
{ "finding_id": "DF-4986", "status": "not_reproduced", "reproduced": 0, "impact": "panic", "confidence": "certain", "verdict": "Sink primitive reproduced live on the stock guest kernel (INVARIANTS X86_64_GENERIC): callout_terminate() of a bzerod callout panics with the exact predicted assertion (panic.txt). The full trigger \u2014 an mfi(4) attach failure unwinding through mfi_pci.c:296-298 into mfi_free() before mfi.c:741 initializes the watchdog callout \u2014 is unconditional straight-line control flow (mfi_pci.c:281 goto out; mfi_attach failures at mfi.c:413-417/428-473/672-706; mfi.c:1074 callout_terminate) and cannot execute on the guest only because no LSI MegaRAID controller exists there. On hardware: boot/kldload kernel panic whenever the card is present but attach fails before watchdog init (e.g. firmware not in READY state).", "exploit_chain": "", "evidence": "panic.txt (live guest panic: assertion \"cc->flags & CALLOUT_DID_INIT\" failed in callout_terminate at kern_timeout.c:1111 from kldload of the primitive module); build.log (module built -Werror clean); df4986_primitive.c (exact sink reproduction); VERDICT.md (full code trace mfi_pci.c:230,281,294-299 -> mfi.c:1074 -> kern_timeout.c:1104-1111)", "kernel_refs": [ "sys/dev/raid/mfi/mfi_pci.c:230", "sys/dev/raid/mfi/mfi_pci.c:279-282", "sys/dev/raid/mfi/mfi_pci.c:294-299", "sys/dev/raid/mfi/mfi.c:741", "sys/dev/raid/mfi/mfi.c:1074", "sys/kern/kern_timeout.c:1104-1111", "sys/config/X86_64_GENERIC:56" ], "poc_changes": "n/a (authored fresh): module reproduces the sink call with the exact softc state (bzerod callout) that the mfi_pci unwind presents to mfi_free(); built in-tree under /usr/src/sys/modules because out-of-tree kmod includes failed.", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 160, "guest_dirty": 0, "build_cmd": "cd /usr/src/sys/modules/df4986 && make", "run_cmd": "kldload /usr/src/sys/modules/df4986/df4986.ko", "code_hash": "166398560d936982e9eccefdacb779c71e92e3778c6963cc12a4e2f15d34d46f", "notes": "Guest wedged in ddb after the primitive panic; reset with-src performed and verified clean (env.txt taken post-reset). Distinct from DF-2031 (IRQ-alloc EINVAL leak at mfi_pci.c:288-292 returns before mfi_free, so it leaks but cannot panic). Without INVARIANTS the unwind is a no-op (cc->toc==NULL), but stock GENERIC ships INVARIANTS. fix_status: not_testable at full-path level (hardware-gated); the primitive-level validation (panic before fix primitive / no panic with initialized callout per code) is covered by the live sink reproduction.", "recommended_fix": "callout_init_mp(&sc->mfi_watchdog_callout) at the top of mfi_pci_attach() right after bzero(sc) and remove the late init in mfi_attach() so every failure unwind terminates an initialized callout", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Hardware-gated: full mfi path cannot run on the guest (no MegaRAID card), so a patched-kernel rebuild cannot be exercised end-to-end. The panic sink itself was reproduced live (panic.txt); fix.diff moves callout_init_mp() ahead of every possible failure unwind, making the panicking state unreachable by construction (single init before any goto out / mfi_attach failure path)." } |