DF-5722 / verdict.json
{ "finding_id": "DF-5722", "status": "reproduced", "reproduced": true, "impact": "panic", "confidence": "certain", "verdict": "Resuming a DDB session that was entered from interrupt context (e.g. any breakpoint in clock/interrupt-path code such as b hardclock) deterministically panics the kernel with td_critcount is/would-go negative at the session-exit crit_exit() (db_interface.c:201 -> crit_exit_wrapper -> crit_panic, lwkt_thread.c:1772): one td_critcount decrement goes unmatched across the session. 3/3 boots on the stock snapshot kernel (UP guest); thread-context controls on the same kernel (sysctl-entry, single-step roundtrip, breakpoint hit in sys_kill resumed with c) are all clean, and the DF-5721 software watchpoint was exonerated by a no-watch bisect run. db_run.cs engine (the audited file) is context-agnostic and exonerated by identical captured state in surviving vs panicking runs; the defect lives in the machine layers crit accounting around kdb_trap for interrupt-context sessions. Root-console-only trigger (all unprivileged routes probed closed), so: Low severity, panic class \u2014 the practical cost is that debugging any interrupt-path code with DDB crashes the box.", "exploit_chain": "", "evidence": "run4-minimal-panic.serial.log (b hardclock / c / Breakpoint at hardclock / d hardclock / c / panic + crit_panic trace); run5-threadctx-control.serial.log (thread-context bp hit + c = alive); panic.watch.serial.log (run1 variant); README.md bisect matrix; three vmcores preserved in guest /var/crash", "kernel_refs": [ "sys/platform/pc64/x86_64/db_interface.c:160", "sys/platform/pc64/x86_64/db_interface.c:201", "sys/kern/lwkt_thread.c:1766", "sys/kern/lwkt_thread.c:1772", "sys/platform/pc64/x86_64/ipl.s:281", "sys/platform/pc64/x86_64/ipl.s:304", "sys/ddb/db_run.c:199", "sys/ddb/db_run.c:164" ], "poc_changes": "No seed PoC. Built from scratch: UP/SMP socket-serial QEMU rigs, paced serial DDB driver, root-sysctl DDB entry, and the bisect battery across 6 boots (3 panic runs, 3 controls).", "attempts": 6, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 UTC 2026 x86_64", "runtime_sec": 1500, "guest_dirty": 0, "build_cmd": "(no compilation; DDB console session over serial socket)", "run_cmd": "./findings/poc/DF-5721/serial_vm1.sh up; ssh dfbsd sysctl debug.enter_debugger=ddb &; DF5721_SOCK=/tmp/opencode/df-5721up-ser.sock ./findings/poc/DF-5721/drive_ddb.py b hardclock 4 c 6 d hardclock 4 c 10", "code_hash": "d2ddfc831df07815aad62268d74dafffd091bac78ffa1e8ddcc391f1cdee803a", "notes": "Exact leak instruction not pinned (needs vmcore unwind; dumps preserved on guest /var/crash before reset). Fix ownership: db_interface.c/ipl.s, discovered during the sys/ddb/db_run.c pass-2 audit. Guest was reset with-src after evidence capture.", "recommended_fix": "kdb_trap: save curthread->td_critcount after crit_enter() and force-restore it at session exit instead of bare crit_exit() (see fix.diff); upstream-quality fix is to find the unmatched decrement in the interrupt-entry/polled-console path.", "fix_status": "not_testable", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "fix.diff authored post-verification against the read-only sys/ tree; not applied/rebuilt \u2014 the panic recipe needs a UP guest and a kernel rebuild on the 1-vCPU guest was not feasible in-run. Baseline (panic) reproduced 3/3.", "fix_evidence": "findings/poc/DF-5722/fix.diff" } |