⬢ DragonFlyBSD Kernel Audit
DF-4423 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4423",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "REPRODUCED on DragonFly 6.5-DEVELOPMENT/X86_64_GENERIC (private KVM guest, vtblk0 as non-root 256MB data disk, detach driven via a helper KLD calling device_detach() = the exact vtblk_detach() path of kldunload/unplug). 96 threads x one 2MB pread (192MB) were mid-flight when vtblk_detach() ran at t=5s: every pread returned full success at the detach instant (errors=0, read_ms ~5000ms for all threads) while QEMUs own block counters show the device transferred only 17,956,864 of the 201,326,592 bytes (8.9%). The other 185MB (91%) of successfully read data was fabricated by vtblk_drain()/strategy-ENXIO completing bios with biodone() without setting B_ERROR/b_error (virtio_blk.c:1202-1207 drops the error argument); userspace received recycled kernel buffer/page contents (stale physical memory from previous boots - leak samples show 0xAA fill and 0x5A marker patterns the device never transferred in the window). Consequences: silent data corruption (unperformed reads/writes reported complete to the fs layer) plus stale-kernel-memory disclosure to any reader of the device. Controls: identical volley without detach = 100% real data (95.81s cold-cache), and the classifier was validated against direct dd+hexdump reads. Not a UAF: post-detach reads error cleanly (EBADF), so the known DF-1605 family did not pollute the run.",
  "exploit_chain": "",
  "evidence": "run_ks2.out (per-thread timing: all read_ms ~4900-5050ms = released exactly at the 5s detach; RESULT ... errors=0), blockstats_s0.txt/blockstats_s1.txt (QEMU rd_bytes delta 17,956,864 vs 201,326,592 guest-visible success bytes), leak_sample_0.bin (0xAA fill pattern) / leak_sample_1.bin (0x5A marker pattern) = fabricated data, env_dmesg.txt (detach trace), VERDICT.md for the full narrative including the 95.81s no-detach control.",
  "kernel_refs": [
    "sys/dev/virtual/virtio/block/virtio_blk.c:1202",
    "sys/dev/virtual/virtio/block/virtio_blk.c:1078",
    "sys/dev/virtual/virtio/block/virtio_blk.c:1103",
    "sys/dev/virtual/virtio/block/virtio_blk.c:532",
    "sys/dev/virtual/virtio/block/virtio_blk.c:543"
  ],
  "poc_changes": "Seed concept (unload driver mid-I/O) had to be rebuilt entirely: virtio_blk is compiled into the audit kernel (kldunload impossible) and DragonFly has no PCI/ACPI hotplug handling (QEMU device_add ignored), so detach was driven by a 30-line helper KLD invoking device_detach() on vtblk0 from a private QEMU instance whose root is on IDE. Tester gained: per-chunk classification (fixed a signed-char comparison bug found via the control run), per-thread CLOCK_MONOTONIC timing, leak-sample dumps, marker mode, and a QEMU blockstats delta protocol to separate real DMA from fabricated completions (host/guest cache made naive garbage bytes checks unreliable).",
  "attempts": 9,
  "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": 5400,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -pthread -o df4423_tester df4423_tester.c && (kmod dir) make  # dfdetach.ko via bsd.kmod.mk",
  "run_cmd": "sh /root/killshot2.sh   # 96x2MB pread volley + device_detach at t=5s; QEMU info blockstats before/after",
  "code_hash": "4daf70c2ffc79d9278dc6e2ff7227527d0044d08993c4861337cd3b25b6475fe",
  "notes": "Private-VM setup documented in VERDICT.md (IDE root + 256MB virtio test disk; loader vfs.root.mountfrom override). Write-path variant (silently lost writes) follows from the same drain path; read variant chosen because fabricated data is directly observable. Main audit guest untouched (overlay discarded).",
  "recommended_fix": "vtblk_finish_bio(): set bp->b_flags|=B_ERROR, bp->b_error (if unset) and bp->b_resid=bp->b_bcount when error!=0, before biodone()",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored from the line-accurate trace; single-fix kernel rebuild not exercised in this run (non-memory-corruption class). Baseline (buggy) behavior reproduced and fully quantified above.",
  "fix_evidence": "fix.diff"
}