⬢ DragonFlyBSD Kernel Audit
DF-5377 / run.patched.log
← back to finding ↓ download raw
# DF-5377 fix-validation runs (patched kernel #2: relpbuf-in-SWI attempt -> OK
# for accounting but wrong context; kernel #3: v3 fix = route disabled-path
# CCBs to user_ccb_queue + cam_periph_unmapmem in targdtor)
# Final validated run (kernel #3, Sat Oct 3 18:32:37):
root@dfbsd# sysctl vm.pbuf_mem_count
vm.pbuf_mem_count: 394
root@dfbsd# ./poc5377 8 x readback
[*] DF-5377: vm.pbuf_mem_count=394; running 8 leak cycles (drain=0)
[*] 8/8 cycles, pbuf_mem_count=393 (leaked so far: 1)
[*] after : vm.pbuf_mem_count=393 (expected 386 = 394-8)
[*] readback: 0 CCBs delivered; vm.pbuf_mem_count=394 (baseline 394)
[+] FIXED: pool fully restored after daemon read the completions
rc=0
root@dfbsd# sysctl vm.pbuf_mem_count
vm.pbuf_mem_count: 394
#
# Post-fix semantics: each cycle's late-completed CTIO now lands on
# user_ccb_queue instead of being discarded; the NEXT targenable's
# periph-cleanup (targdtor, running in the daemon's ioctl thread, where
# cam_periph_unmapmem()'s copyout+relpbuf are legal) releases the bounce
# pbuf immediately -- hence at most ONE outstanding pbuf at any time
# (393 at the measurement point) and a full return to baseline (394)
# with zero permanent loss, versus the unpatched -1-per-cycle-forever
# behavior and the full 394->0 drain + unkillable wswbuf5 dd wedge.
#
# v1 fix attempt (cam_periph_unmapmem directly in targdone) was REFUTED
# on the guest: targdone runs in the cambio SWI where copyout() is
# illegal -- Fatal trap 12 at copyout+0x14 (current process Idle).
# v2 (relpbuf-only in targdone) was REFUTED: the pbuf is BUF_LOCK()ed
# by the mapping thread -- panic "lockmgr: pid -1, not exclusive lock
# holder" at relpbuf <- targdone <- camisr_runqueue.  v3 (validated)
# moves the release into daemon context as the API documents.