{
  "finding_id": "DF-2513",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "corruption",
  "confidence": "certain",
  "verdict": "The verbatim nvme_admin_state_identify_ns computes nsc->blksize = 1 << lbafmt->sect_size (nvme_admin.c:673-675) with sect_size a device-controlled uint8_t from the Identify Namespace DMA and no range check. The rig refills the crafted Identify response at the DMA-completion boundary (after the drivers bzero of req->info - the first version filled too early and the bzero wiped it). Results: sect_size=9 -> 512 (legal control); 31 -> 0x80000000 (2GiB blocks); 36 -> 16 (shift count masked to 5 bits - C11 UB); 63 -> 0x80000000. The garbage blksize is what nvme_disk_attach publishes as the namespace media block size (geometry/media-size corruption; divisor in I/O sizing). Fixed source (reject formats outside 9..12, skip attach) A/B: attach count 0, no garbage published.",
  "exploit_chain": "hostile/faulty NVMe controller (PCI trust); geometry corruption; no memory-safety violation by itself.",
  "evidence": "run.log: blksize 512/2147483648/16/2147483648 for sect_size 9/31/36/63; fixed: attach skipped.",
  "kernel_refs": [
    "sys/dev/disk/nvme/nvme_admin.c:673",
    "sys/dev/disk/nvme/nvme_admin.c:675",
    "sys/dev/disk/nvme/nvme_ident.h:234",
    "sys/dev/disk/nvme/nvme_disk.c"
  ],
  "poc_changes": "DMA refill hook moved into the interposed wait/completion (bzero ordering); first rig version was self-defeating.",
  "attempts": 2,
  "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": 500,
  "guest_dirty": 0,
  "build_cmd": "sh /root/rigs/dfv_nvme/gen.sh && make -m /usr/src/share/mk (in dfv_nvme)",
  "run_cmd": "kldload dfv_nvme.ko; for s in 9 31 36 63; do sysctl kern.dfv_nvme_run=$s >/dev/null; sysctl -n kern.dfv_nvme_status; done",
  "code_hash": "df5fe33593aad934bb0be9166c045695e2852eeb26bfd94e3b3b4ddb54a4d742",
  "notes": "shift-by->31 is C11 UB; on this target the count masks to 5 bits so the device selects any 1<<(n&31); sect_size=31 -> 0x80000000. Fixed code rejects formats outside 9..12 (attach skipped, count 0).",
  "recommended_fix": "validate lbafmt->sect_size (9..12) before the shift",
  "fix_status": "fixed"
}