{
 "finding_id": "DF-3111",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "dos",
 "confidence": "certain",
 "verdict": "hammer_direntry_namekey() ALG1 returns namekeys up to 0x7fffffffffff0000 with max_iterations=0xffffff and no guarantee that key+max_iterations stays positive; the nlookup/nrename/dounlink consumers do an unchecked signed cursor.key_end.key += max_iterations that wraps negative for crafted filenames, and hammer_btree_iterate() then truncates the directory hash-chain scan to its first element. An unprivileged user (GF(2)-inverting CRC-32 to craft two distinct names with an identical wrap-zone namekey) creates a permanently unfindable, permanently unremovable dirent that persists across remounts/reboots, plus an unremovable dirent+inode leak on every re-create: durable local filesystem poisoning / disk-space exhaustion. No memory corruption.",
 "exploit_chain": "solve wrap-zone name pair via 4-byte CRC-32 GF(2) inversion (segment-sum -> 0x7fffffff top bucket) + 3 alphabet brute bytes (whole-name crc zone) -> create nameA at key K -> create nameB (collision-bumped to K+1) -> lookup(nameB): btree_search returns nameAs record (first element >= K), bcmp fails, hammer_btree_iterate rejects K+1 vs wrapped negative key_end -> ENOENT forever; readdir still lists it; each further O_CREAT after a namecache miss appends another unremovable dirent at K+2, K+3, ...",
 "evidence": [
  "run.log: stage1 unlink nameB : No such file or directory <-- BUG + readdir nameB cnt : 1",
  "run.log: stage3 persist stat nameB : No such file or directory <-- POISONED, persist unlink nameB : No such file or directory <-- UNREMOVABLE, after 5 re-creates ... cnt = 2 (was 1) <-- LEAK",
  "fix_run.log: same pair on fix.diff kernel: persist stat nameB : OK, persist unlink nameB : OK, cnt stays 1 after 5 re-creates"
 ],
 "kernel_refs": [
  "sys/vfs/hammer/hammer_subs.c:943",
  "sys/vfs/hammer/hammer_subs.c:963",
  "sys/vfs/hammer/hammer_subs.c:1024",
  "sys/vfs/hammer/hammer_vnops.c:1234",
  "sys/vfs/hammer/hammer_vnops.c:2014",
  "sys/vfs/hammer/hammer_vnops.c:3324",
  "sys/vfs/hammer/hammer_btree.c:216",
  "sys/vfs/hammer/hammer_btree.c:277",
  "sys/vfs/hammer/hammer_object.c:705",
  "sys/vfs/hammer/hammer_inode.c:858"
 ],
 "poc_changes": "seed concept was image-crafted namekeys at wrap; actual unprivileged vector required (1) a deterministic identical-key PAIR solver (4-byte CRC-32 GF(2) inversion for the segment-sum + 3 alphabet brute bytes for the whole-name crc wrap zone; an append-4-bytes-to-state inversion is rank-deficient and was discarded), (2) create-order discipline (nameA keeps slot K occupied so nameB is bumped to K+1), (3) remount between create and probe to flush dirents to disk and cold the positive namecache that otherwise masks stat/open; trigger+recheck run as uid/gid 65534",
 "attempts": 3,
 "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": 2100,
 "guest_dirty": 0,
 "build_cmd": "cc -O2 -o /root/trig /root/trig.c && cc -O2 -o /root/recheck /root/recheck.c",
 "run_cmd": "sh /root/run.sh  (root for fs setup; PoC stages drop to uid 65534)",
 "code_hash": "73ab06608146d97b",
 "notes": "hammer1 v7 image via newfs_hammer -f (v>=6 selects DIRHASH_ALG1 for new dirs, hammer_inode.c:858-862); plain libkern crc32 (not hammer_datacrc) used by namekey, verified vs solver; kernel built with -fno-strict-overflow so the wrap is deterministic; create-side ++key walk past INT64_MAX (hammer_object.c:708 KKASSERT) noted but impractical (needs ~16M successive occupied keys); fix validated on rebuilt kernel #1",
 "recommended_fix": "clamp *max_iterationsp in hammer_direntry_namekey() so key + max_iterations <= INT64_MAX",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Sun Sep 6 12:02:37 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_verdict": "fix.diff applied to /usr/src in guest, make nativekernel + installkernel + reboot (kernel #1); exact PoC re-run: stage1 unlink nameB : OK + readdir cnt 0; focused durable check (pair created, remounted): persist stat nameB : OK, persist unlink nameB : OK, no leak after 5 re-creates \u2014 poisoning gone",
 "fix_evidence": [
  "fix_run.log",
  "fix_run_stage1.log",
  "fix.diff"
 ]
}