DF-3514 / verdict.json
{ "finding_id": "DF-3514", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "ng_ID_rehash/ng_name_rehash migrate hash entries with LIST_REMOVE guarded by #ifdef INVARIANTS; on production kernels and standalone KLD builds every entry remains double-inserted, so hashdestroy on the old table panics (hashdestroy: hash not empty); ng_ID_rehash also destroys the old ID table with the name-hash mask. Reproduced 4x on the guest (3x ID path, 1x name path); node-count threshold is permanently crossed by the DF-3513/DF-3515 node-reference leaks, so routine traffic converts this into a reliable kernel panic. Fix (unconditional LIST_REMOVE + correct mask) validated at module level: the previously-panicking workload survived 20/20 cycles.", "exploit_chain": "DF-3513/DF-3515 leaks pin ng_nodes -> ng_nodes*2 > ng_ID_hmask -> ng_make_node_common calls ng_ID_rehash on next node creation (any subsystem) -> double-insert + hashdestroy -> kernel panic; related slab-heap corruption observed once (chunk_mark_allocated assertion) consistent with the double-insert UAF", "evidence": "panic.txt (4 distinct traces); fix.diff; VERDICT.md baseline-vs-fixed run counts", "kernel_refs": [ "sys/netgraph7/netgraph/ng_base.c:986-996", "sys/netgraph7/netgraph/ng_base.c:953-962", "sys/netgraph7/netgraph/ng_base.c:645-661" ], "poc_changes": "reuses DF-3513 poc_leak harness; panic reproduction needed no extra code beyond repeated runs", "attempts": 4, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 x86_64", "runtime_sec": 1200, "guest_dirty": 1, "build_cmd": "see DF-3513 build.sh", "run_cmd": "for i in 1..10: ./poc_leak 500 (panic on unfixed core module)", "code_hash": "", "notes": "module-build caveat: standalone KLD builds do not define INVARIANTS even on INVARIANTS kernels \u2014 the guest reproduced the production-kernel behavior exactly", "recommended_fix": "unconditional LIST_REMOVE in both rehash loops; hashdestroy(..., ng_ID_hmask)" } |