{
  "finding_id": "DF-2632",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Reproduced standalone on the stock INVARIANTS kernel: filling one hammer2 directory with ~100 CRC32C-multicollision names (same 64K dirhash window) panics the flusher via hammer2_flush_core -> hammer2_chain_indirect_maintenance -> hammer2_chain_rename_obref -> hammer2_base_insert ('insert base %p overlapping elements', chain.c:5308-5311; on INVARIANTS kernels the panic path's unconditional spin_unex at :5309 additionally corrupts td_critcount and reports 'td_critcount is/would-go negative'). Deterministic threshold measured at 96<N<=112 same-window dirents with per-16 syncs. The fix kernel's diagnostic proved the root cause: nested indirect-block key ranges (identical normalized base key deadbeef60428000, elm keybits 7 vs existing base[0] keybits 5) from create/flush interleaving under dense packing. Natural names cannot trigger it (window index carries ~47 bits of CRC entropy; 50000 natural names = max 1 per window, no panic), so the trigger requires deliberate multicollision construction - unprivileged local DoS, Medium. fix.diff (base_insert returns error + skip before stats side effects, no spinlock touch in the defer path; indirect-maintenance pre-flight abort of the whole collapse before any destructive step; flush_core retry-on-defer; rate-limited kprintf) validated on an identical-config rebuilt kernel: 19818 dense entries created with zero errors, no panic, all files survive umount+remount, natural-name dirs and healthy-image roundtrips unaffected.",
  "exploit_chain": "unprivileged user with write access to one hammer2 directory: (1) generate ~200 8-char names sharing one CRC32C via meet-in-the-middle (gen_names.c, ~5s); (2) create the files with periodic sync(); (3) flusher's indirect-maintenance collapse hits the nested-range overlap at ~100 entries and panics the kernel - denial of service (no privilege escalation path; the bug is a topology-consistency panic, not memory corruption).",
  "evidence": [
    "serial_panic_stock_standalone.log - fresh stock panic: crit_panic <- spin_unlock <- hammer2_base_insert <- hammer2_chain_rename_obref <- hammer2_chain_indirect_maintenance",
    "density_probe.log + serial_panic_density96.log - deterministic threshold 96<N<=112 dense dirents",
    "natural_probe.log - 50000 natural names: max-per-window=1, no panic (trigger needs crafted collisions)",
    "fix_validation.log + fix_validation_part2.log + fix_run.log - fixed kernel: 19818 dense entries, 0 errors, all files survive remount; natural + roundtrip unaffected",
    "iteration1_assert.log - intermediate defer-in-loop variant tripped repchange KKASSERT; root-cause for the pre-flight design",
    "VERDICT.md section 2 - the overlap diagnostic: elm deadbeef60428000/7 vs base[0] deadbeef60428000/5 (nested ranges)"
  ],
  "kernel_refs": [
    "sys/vfs/hammer2/hammer2_chain.c:5308-5311",
    "sys/vfs/hammer2/hammer2_chain.c:5309",
    "sys/vfs/hammer2/hammer2_chain.c:4921-5001",
    "sys/vfs/hammer2/hammer2_chain.c:4065-4231",
    "sys/vfs/hammer2/hammer2_chain.c:4215-4217",
    "sys/vfs/hammer2/hammer2_chain.c:3487-3509",
    "sys/vfs/hammer2/hammer2_chain.c:3501",
    "sys/vfs/hammer2/hammer2_chain.c:3829",
    "sys/vfs/hammer2/hammer2_chain.c:4651-4673",
    "sys/vfs/hammer2/hammer2_chain.c:2314",
    "sys/vfs/hammer2/hammer2_flush.c:1039-1042",
    "sys/vfs/hammer2/hammer2_flush.c:1116-1134",
    "sys/vfs/hammer2/hammer2_subr.c:178-229",
    "sys/vfs/hammer2/hammer2_inode.c:1311-1327",
    "sys/sys/thread2.h:220-223"
  ],
  "poc_changes": "Materialized standalone triggers from the DF-2628 transcripts: fill2632.c (batch fill + progress so the panic-time count survives the dying ssh session), denseprobe.c (fine-grained density bracketing), naturalprobe.c (userland hammer2_dirhash replica + natural-name negative control). Adapted gen_names.c unchanged from DF-2628.",
  "attempts": 5,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 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": 7200,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -o gen_names gen_names.c && cc -O2 -o fill2632 fill2632.c && cc -O2 -o denseprobe denseprobe.c && cc -O2 -o naturalprobe naturalprobe.c",
  "run_cmd": "sh run_df2632.sh  (stock: panic) / sh validate_fix.sh  (fixed: no panic)",
  "code_hash": "b45bec5132627c745e30cc0ce0cc2100cc97981a423d2cc4a34d6840d25d54b4",
  "notes": "Fix validation milestone stopped at 19818/32768 window entries (180x the stock panic threshold) because deferred-collapse retries slow per-entry creation as the window deepens; zero errors, zero panics, all data intact after remount. Residual: the nested-range creation itself (indkey_dir split normalization) is a deeper topology issue; this fix makes it non-fatal and deferred.",
  "recommended_fix": "hammer2_base_insert: skip+defer on overlap (error return, no stats side effects, no spinlock manipulation, rate-limited diagnostic) and abort indirect-maintenance collapses in a pre-flight key-range check before any destructive step, instead of panicking.",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly 6.5-DEVELOPMENT #2: Sat Aug 29 08:00:46 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "A/B on identical KERNCONF (X86_64_GENERIC, INVARIANTS): stock #0 panics at 96-112 dense dirents; fixed #2 filled 19818 dense dirents with zero errors and zero panics, all 19818 files present after umount+remount; natural-name dirs (22000 entries, max 1/window) and healthy-image md5 roundtrips unaffected; console shows the rate-limited defer notice (1/s) instead of the panic. The previously-observed bad behavior is GONE.",
  "fix_evidence": "fix_validation.log, fix_validation_part2.log, fix_run.log, iteration1_assert.log, fix_build.log"
}
