⬢ DragonFlyBSD Kernel Audit
DF-2890 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-2890",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "denial_of_service",
 "confidence": "likely",
 "verdict": "OOB read executed on the live kernel with an instrumented replica of the stock loops. With size = (v_page_count + 64) pages and high = BUS_SPACE_MAXADDR (0xFFFFFFFFFFFFFFFF, cpu/x86_64/include/bus_dma.h:47), the :331 pre-check (phys+size > high) PASSES (phys+size = 0x1e775e000), and the verify loop condition (i < start + size/PAGE_SIZE, vm_contig.c:377) has no v_page_count bound: with a tail candidate (start = v_page_count - 4) the loop read pga[998273]..pga[998276] - four REAL one-past-end reads at 0xfffff80047a04180.. executed (values returned to the harness log); the loop would otherwise run to index 1996606 = 2x the array. Compare-only OOB read of adjacent kernel memory (no disclosure channel); the practical impact is the O(n^2) rewalk plus 3 full page-queue flush passes stalling all contigmalloc callers. No in-tree attacker-reachable oversized caller (cpuctl clamps; DRM/netmap gated) - defense in depth.",
 "exploit_chain": "",
 "evidence": "run.log DF2890 lines: OOB READ idx=998275/998276 word0=0x0; pre-check PASSES; loop runs to 1996606",
 "kernel_refs": [
  "sys/vm/vm_contig.c:377",
  "sys/vm/vm_contig.c:331",
  "sys/vm/vm_contig.c:398"
 ],
 "poc_changes": "replica harness (function is static); reads limited to 4 past-end elements for safety",
 "attempts": 1,
 "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:04 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
 "runtime_sec": 30,
 "guest_dirty": 0,
 "build_cmd": "make (KMOD dfv_safe)",
 "run_cmd": "kldload dfv_safe.ko; sysctl -w dfv.cg2890=1; dmesg | grep DF2890",
 "code_hash": "8211ab6aada2d050ed579802377f08a3b6aeddeabcc33fd0679d43540120a7f4",
 "notes": "no unpriv trigger in tree; also demonstrated wrap arithmetic for phys+size near 2^64",
 "recommended_fix": "bound both loops by vmstats.v_page_count and reject candidates whose span cannot fit the array",
 "fix_status": "not_testable",
 "fix_verdict": "fix compiled in fix-all kernel; replica logic shows fixed loop stops at v_page_count"
}