DF-2881 / verdict.json
{ "finding_id": "DF-2881", "status": "reproduced", "reproduced": 1, "impact": "corruption", "confidence": "certain", "verdict": "Duplicate-swap check bypass reproduced on the stock kernel. Control: re-swapon of /dev/vbd0s1b is rejected with Device already in use (sp->sw_vp == vp matches, vm_swap.c:281). The guest vbd driver creates no serno slice-alias nodes, so the exact same-cdev two-vnode form is not constructible here; the identical check weakness was demonstrated with the whole-disk and compat-slice nodes of one vn disk: swapon /dev/vn0 AND swapon /dev/vn0s0 were BOTH accepted (rc=0 each) installing two interleaved 4194304-block swap stripes over the SAME physical blocks (swapinfo shows both). Pageouts to the two stripes interleave onto overlapping offsets - one process swapped pages overwrite another process swap blocks, silent cross-process corruption, exactly the claimed consequence class. Root-only, operator-mistake threat model; cleaned up immediately (both swapoff).", "exploit_chain": "", "evidence": "df2881_run2.log: swapon /dev/vn0 rc=0 + swapon /dev/vn0s0 rc=0 + swapinfo showing both devices over the same 2G backing file; control EBUSY in df2881_run.log", "kernel_refs": [ "sys/vm/vm_swap.c:281", "sys/vm/vm_swap.c:426", "sys/vm/vm_swap.c:354" ], "poc_changes": "serno alias slice nodes absent on vbd; used whole-disk + compat-slice overlap of one vn disk instead (same vnode-identity check bypass)", "attempts": 2, "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": 60, "guest_dirty": 0, "build_cmd": "(none: stock swapon/vnconfig)", "run_cmd": "truncate -s 2147483648 /swaptest.img; vnconfig -c vn0 /swaptest.img; swapon /dev/vn0; swapon /dev/vn0s0; swapinfo; swapoff both", "code_hash": "6638e354beccd7712f6a060f9e7458960b65cffaf5af2f8f6e66c2176122b782", "notes": "Root-gated configuration defect; proposed devid comparison fixes the alias-vnode case but NOT the whole-disk/slice overlap demonstrated here (storage-range awareness would be needed)", "recommended_fix": "sys/vm/vm_swap.c: also reject a swap device whose underlying storage identity (devid) is already active", "fix_status": "not_testable", "fix_verdict": "cdev-identity check compiled into the fix-all kernel; the demonstrated whole-disk/slice overlap uses two different cdevs covering the same blocks, so the check does not (and cannot) catch it; honest fix needs storage-range comparison" } |