DF-2644 / verdict.json
{ "finding_id": "DF-2644", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "REPRODUCED on fault-injection kernel A (stock + sysctl-gated EIO injector with byte-exact real-media semantics, volume-gated to the 512MB test fs): sync on a PFS whose iroot chain cannot be re-read panics with Fatal trap 12, fault VA 0x200, 'Stopped at hammer2_xop_inode_flush+0x39c: repe movsq' - exactly the unguarded 'pmp->pfs_iroot_blocksets[clindex] = chain->data->ipdata.u.blockset' at hammer2_flush.c:1336-1337 with chain->data == NULL after hammer2_chain_load_data EIO (chain.c:1003-1008). The designed handlers one frame away ('hammer2: chain error during flush', 'PARENT ERROR DURING FLUSH LOCK') demonstrably work; this single deref ignores both chain->error and the discarded hammer2_flush() return. Fix validated on kernel B (only delta = fix.diff): identical workload+message sequence passes the site with no fault; residual later panic is the unrelated pre-existing chain.c:3112 KKASSERT(parent->error==0) via create/strategy retry paths (documented, belongs to chain.c audit).", "exploit_chain": "", "evidence": [ "findings/poc/DF-2644/panic.txt (kernel A serial: chain-error handler messages then Fatal trap 12 VA 0x200 at hammer2_xop_inode_flush+0x39c)", "findings/poc/DF-2644/fix_run.log (kernel B: same sequence, NO xop_inode_flush fault, residual 3112 panic)", "findings/poc/DF-2644/fix_run_partial_3112.txt (kernel B arm=100000 variant, annotated contrast vs kernel A)", "findings/poc/DF-2644/inject.diff (environment simulator, never applied to the audited sys/ tree)", "findings/poc/DF-2644/fix.diff (the fix: guard + flush_error propagation)", "findings/poc/DF-2644/run_df2644_inj.sh, validate_fix_df2644.sh (triggers)", "findings/poc/DF-2644/build_kernelA2.sh / build_kernelB.sh (nativekernel build drivers)", "findings/poc/DF-2644/VERDICT.md (full narrative)" ], "kernel_refs": [ "sys/vfs/hammer2/hammer2_flush.c:1334-1338", "sys/vfs/hammer2/hammer2_flush.c:1319-1322", "sys/vfs/hammer2/hammer2_flush.c:671-679", "sys/vfs/hammer2/hammer2_chain.c:998-1009", "sys/vfs/hammer2/hammer2_chain.c:147-166" ], "poc_changes": "Original sketch (vn detach / truncate backing file) was unrunnable: VNIOCDETACH refuses while the mount holds the device (vn.c:464), truncation yields short reads without B_ERROR (vn.c:342-371). Replaced with a sysctl-gated EIO injector inside _hammer2_io_getblk (after DIO setup, exactly where breadnx reports errors); first injector revision returning *diop=NULL was itself an artifact (violated the always-valid-dio contract, crashed in _hammer2_io_putblk) and was corrected to error-injection; volume-gated by volu_size after the guest ROOT hammer2 was also being failed (its boot-time writes panicked via chain.c:3112). Trigger v2 uses metadata-only dirt + bounded arm count.", "attempts": 6, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Sat Aug 29 19:59:33 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (kernel A, panic run)", "runtime_sec": 6900, "guest_dirty": 0, "build_cmd": "cd /usr/src && make -j6 nativekernel KERNCONF=X86_64_GENERIC && make installkernel KERNCONF=X86_64_GENERIC", "run_cmd": "sh /root/df2644/run_df2644_inj.sh", "code_hash": "see manifest.json artifacts_sha256", "notes": "Residual panic chain.c:3112 (KKASSERT parent->error==0 via xop_inode_create_ins / assign_physical) is a separate defect surfaced by the same scenario - recommend filing under hammer2_chain.c. Injector never touches the audited sys/ tree; guest reset with-src after runs.", "recommended_fix": "Guard the blockset copy with 'chain->error == 0 && chain->data != NULL' and propagate hammer2_flush()'s return into flush_error so a failed iroot flush also skips volume-header sync (fix.diff)", "fix_status": "fixed", "fix_kernel_uname": "DragonFly 6.5-DEVELOPMENT kernel B (only delta = fix.diff; in-guest nativekernel)", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "kernel B (stock + DF-2644 fix.diff only) passes the identical EIO-injected sequence with no fault at the site; the designed error handlers operate.", "fix_evidence": "fix_build.log / fix_run.log / VERDICT.md" } |