{
  "finding_id": "DF-5812",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "swaponvp() (sys/vm/vm_swap.c:365-366) rounds the swap device page count UP to the SWB_DMMAX (64-page) stripe boundary and frees the full padded stripes into the swap blist (vm_swap.c:377-383). For any swap device whose size is not a multiple of 256KB, 1..63 pages of non-existent phantom swap are published (vm_swap_size/swapinfo overstate the device; the strategy-layer bound check at vm_swap.c:128 uses the padded sw_nblks). Under unprivileged memory churn, pageout allocations reach the phantom tail; the OOB swap write is rejected by the backend (EINVAL) and the write-error path (swap_pager.c:1965-1994 -> swp_pager_freeswapspace at swap_pager.c:583-603) frees the phantom block back to the blist and redirties the page, so the pageout daemon reallocates the same phantom block forever: the guest wedged in an infinite swap_pager: I/O error - pageout failed; offset 3444736 ... error 22 loop (interleave page 841 = vn0 device page 201 = first phantom page of a 200-page device) and required a hard reset. On backends that do not bounds-check past-EOF I/O the same bug is a silent OOB write of page data past the end of the swap device.",
  "exploit_chain": "admin swapon on an unaligned-size device (e.g. odd-sized swap file/partition) -> blist contains phantom free blocks -> any local users anonymous-memory churn drives pageout into the phantom tail -> backend rejects OOB write (EINVAL) -> error handler frees phantom block back to blist + redirties page -> pageout reallocates identical block -> infinite retry livelock; console spam at line rate; system unresponsive (ssh dead); hard reset required. Ceiling: DoS (demonstrated) / silent cross-partition write on non-checking backends.",
  "evidence": "run.log steps 0-3: vm.swap_size delta +192 pages on swapon of a 200-page vn0 and swapinfo showing /dev/vn0 2048 512-blocks (1MB) for an 800KB file; hang-serial-console.txt: infinite swap_pager: I/O error - pageout failed; offset 3444736, size 65536, error 22 (page 841 -> seg 13 -> device slot 1 vn0 -> device page 201 = phantom) with the guest wedged; fix_run.log: same PoC on the patched kernel shows +128 pages, swapinfo 1536 512-blocks, file unchanged, clean churn and swapoff.",
  "kernel_refs": [
    "sys/vm/vm_swap.c:365",
    "sys/vm/vm_swap.c:367",
    "sys/vm/vm_swap.c:377",
    "sys/vm/vm_swap.c:128",
    "sys/vm/swap_pager.c:537",
    "sys/vm/swap_pager.c:583",
    "sys/vm/swap_pager.c:1965"
  ],
  "poc_changes": "No seed PoC existed; authored fresh: churn.c (anonymous malloc+touch helper) and run.sh (200-page vn swap file, swapon, swapinfo/sysctl capture, 4600MB churn, file-size evidence, teardown). First run attempt aborted on sysctl vm.swap_max being unexported on this kernel; script hardened to tolerate it.",
  "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 (baseline) / #1: Tue Oct 13 02:09:45 UTC 2026 (patched)",
  "runtime_sec": 5400,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -o /root/churn /root/churn.c",
  "run_cmd": "sh /root/run.sh  (creates 200-page /root/swapfile, vnconfig -c vn0, swapon /dev/vn0, /root/churn 4600, evidence, swapoff/teardown)",
  "code_hash": "346c96b075be194c01d769845ac858b819ad4fb89278758897f8261a6701928f",
  "notes": "Memory-corruption-class manifestation is the OOB swap write target past device EOF (bounded to <=63 pages/device, blist-chosen not attacker-chosen); on the vn file backend it surfaces as EINVAL + livelock rather than silent corruption, so the demonstrated impact bucket is dos. MB-aligned default installs are unaffected (sizes multiple of 256KB). Not a uid0 vector: write offset/content are not attacker-directed.",
  "recommended_fix": "In swaponvp() round the device size DOWN to the stripe boundary instead of UP: aligned_nblks = nblks & ~SWB_DMMASK (see fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff (single line: round down) applied to the guest /usr/src, kernel rebuilt via make nativekernel (full log fix_build.log), installed and rebooted (kernel #1 Oct 13 02:09:45). Identical PoC re-run: vm.swap_size delta +128 (was +192), swapinfo vn0 1536 512-blocks (was 2048), backing file unchanged after the identical 4600MB churn (was wedged in the error loop), swapoff succeeded. Every baseline artifact of the bug is gone; fix_patched_reproduced=0 means the bad behavior did NOT reproduce on the patched kernel.",
  "fix_evidence": "fix_run.log (full patched run, steps 0-5 complete with NOT-REPRODUCED marker and clean teardown); fix_build.log (full nativekernel build); VERDICT.md baseline-vs-patched table."
}