DF-2645 / verdict.json
{ "finding_id": "DF-2645", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Code-proven race: hammer2_flush_core (hammer2_flush.c:1039-1042) drives indirect_maintenance, whose collapse-loop skip guard (hammer2_chain.c:4202-4209, bcmp mismatch after a concurrent frontend COW modify of a child) contradicts the unconditional emptiness KKASSERT in hammer2_chain_repchange (chain.c:2314) called at chain.c:4228 -> panic (DoS) on stock kernels, orphaned subtree/silent data loss otherwise. Two stress runs (~130M appends + churn + 20Hz syncs) did not win the scheduler interleaving; run 2 was sabotaged by an unrelated ENOSPC flush storm (DF-2633 family) after the churn filled the 512MB volume. All markers (LOST CHILD, debug repchange, excessive loops) absent from dmesg.", "exploit_chain": "", "evidence": [ "findings/poc/DF-2645/VERDICT.md (full code-path proof with path:line)", "findings/poc/DF-2645/stress2645.c (writers + churn harness)", "findings/poc/DF-2645/run_df2645.sh (driver)", "full_run.log / full_run2.log captured on guest /root/df2645/ (summarized in VERDICT.md)" ], "kernel_refs": [ "sys/vfs/hammer2/hammer2_flush.c:1039-1042", "sys/vfs/hammer2/hammer2_chain.c:4202-4209", "sys/vfs/hammer2/hammer2_chain.c:4228", "sys/vfs/hammer2/hammer2_chain.c:2310-2314", "sys/vfs/hammer2/hammer2_chain.c:4160" ], "poc_changes": "n/a (original trigger sketch replaced by stress2645.c family; harness iterated twice)", "attempts": 2, "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": 2100, "guest_dirty": 0, "build_cmd": "cc -O2 -o stress2645 stress2645.c && cc -O2 -o mknames mknames.c && cc -O2 -o mkfiles mkfiles.c && cc -O2 -o delsome delsome.c", "run_cmd": "sh run_df2645.sh 12 1", "code_hash": "", "notes": "Attempt 2's wedged sync + 'hammer2_flush: error=00000020' spam is ENOSPC (0x20) from flush.c:1057-1064 retry behavior on a full volume - DF-2633 family, deliberately not claimed here.", "recommended_fix": "Abort the collapse before the destructive chain delete when any child was skipped (defer hammer2_chain_delete(parent,chain) until after a clean full sweep), keeping repchange's invariant true" } |