DF-5372 / verdict.json
{ "finding_id": "DF-5372", "status": "reproduced", "reproduced": true, "impact": "dos", "confidence": "certain", "verdict": "_bus_dmamap_sync() (sys/platform/vkernel64/platform/busdma_machdep.c:903-940) dispatches the sync operation with switch (op), but bus_dmasync_op_t is a bitmask (sys/sys/bus_dma.h:118-121): the legal combined operation BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTREAD (0x06) matches no case and BOTH bcopy loops are skipped - a silent no-op that drops the pre-write copy (device then DMAs stale, previously-bounced data from the shared bounce pool) and the post-read copy (device-written data never reaches the client buffer). Proven in a live VKERNEL64 vkernel with a compiled-in driver: control sync(PREWRITE) copies correctly, while sync(PREWRITE|POSTREAD) leaves both the planted bounce-page contents and the client buffer untouched (SILENT NO-OP (bug confirmed), VERDICT PROVEN). pc64 fixed this with bitmask if-tests (pc64 busdma_machdep.c ~:1044); the vkernel64 fork never received the change. fix.diff (bitmask form, mirroring pc64) validated: combined op then reports honored and the VERDICT flips to NOT PROVEN (bug gone). Recorded impact dos = strongest demonstrated end state (functional corruption of DMAd data); no stock VKERNEL64 driver uses bus_dma, so reachability needs a kldloaded bus_dma driver using combined sync ops - Low severity.", "exploit_chain": "bounce-attached map (e.g. 8192-alignment tag under default hw.busdma.bounce_alignment=1, or lowaddr-constrained tag) -> driver issues bus_dmamap_sync(tag, map, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTREAD) -> switch matches no case -> no bcopy in either direction -> device reads stale bounce contents / device writes never copied back (data corruption and cross-buffer data confusion within the vkernel)", "evidence": "run.log (baseline): DF5372: PREWRITE alone: copy ok (control), DF5372: combined PREWRITE|POSTREAD: SILENT NO-OP (bug confirmed), DF5372: VERDICT PROVEN - combined op copies nothing. run.fixed.log (after fix.diff): DF5372: combined PREWRITE|POSTREAD: honored, DF5372: VERDICT NOT PROVEN. env.txt: hw.busdma.bounce_alignment=1.", "kernel_refs": [ "sys/platform/vkernel64/platform/busdma_machdep.c:903", "sys/platform/vkernel64/platform/busdma_machdep.c:913", "sys/platform/vkernel64/platform/busdma_machdep.c:924", "sys/sys/bus_dma.h:118", "sys/platform/pc64/x86_64/busdma_machdep.c:1044" ], "poc_changes": "authored fresh (shared rig with DF-5370). Notables: the driver peeks the private struct bounce_page via a mirror (first word of map->bpages.stqh_first -> vaddr) to observe bounce contents directly; DFly STAILQ_HEAD has two pointers (sizeof(bus_dmamap)=72).", "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 (vkernel = nativekernel VKERNEL64)", "runtime_sec": 9600, "guest_dirty": 0, "build_cmd": "sh /root/build_kernel.sh && sh /root/build_image.sh", "run_cmd": "sh /root/run.sh /tmp/vkconsole.baseline.log (DF5372 lines; same boot as DF-5370)", "code_hash": "bb24de35ada35f7d7e31aec07c65bb49cd7971e1871f3001ce8b62079738fcd7", "notes": "Deterministic, non-crashing. Fix validation was layered after DF-5370s destroy/unload fix (both applied together in run.fixed.log); the sync hunks context is local to the switch and applies to the pristine file independently. Guest restored to pristine busdma source and baseline rebuilt/re-verified; guest reset with-src afterwards.", "recommended_fix": "Replace switch (op) with bitmask tests: if (op & BUS_DMASYNC_PREWRITE) {pre-write bcopy loop}; if (op & BUS_DMASYNC_POSTREAD) {post-read bcopy loop} - mirrors pc64; see fix.diff (validated)", "fix_status": "fixed", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "fix.diff applied (bitmask dispatch), VKERNEL64 rebuilt. Baseline: combined op SILENT NO-OP, VERDICT PROVEN (bug present). Patched: combined PREWRITE|POSTREAD: honored, VERDICT NOT PROVEN - both copies execute; control PREWRITE still copies; vkernel ALIVE.", "fix_evidence": "run.fixed.log: DF5372: combined PREWRITE|POSTREAD: honored + DF5372: VERDICT NOT PROVEN; fix-build.log full rebuild output; fix.diff git-apply-able (independent hunk)" } |