⬢ DragonFlyBSD Kernel Audit
DF-4027 / run.log
← back to finding ↓ download raw
BUILD_OK
sili_ata_cmd(POLL) -> sili_poll():
  probed ccb state: ONCHIP
  poll timeout -> sili_ata_cmd_timeout -> sili_core_timeout:
  DEFERRED (returned 1; state stays ONCHIP)
  sili_poll returns xa->state == ONCHIP to the caller
  sili_cam.c:315 'if (sili_ata_cmd(xa) != ATA_S_COMPLETE)'
    -> sili_ata_put_xfer(xa): sili_put_ccb() puts the ccb
       on ap_ccb_free and bumps serial      (sili.c:2020-2030)
    PORT STILL OWNS IT: ap_active bit set, ap_expired bit set

next command reuses the freed ccb:
  sili_get_ccb -> state==PUT check passes (sili.c:2010)
  sili_ata_cmd -> sili_load_prb loads a NEW dmamap
  sili_issue_pending_commands: ap_active |= 1<<slot AGAIN
  -> ap_active_cnt inflated; two logical commands on one slot

device finally completes / port drains:
  sili_port_reinit expired loop (sili.c:403-413):
    ccb->ccb_xa.state = ATA_S_TIMEOUT;
    ccb->ccb_done(ccb);          <- sili_ata_cmd_done:
       sili_unload_prb()         <- unloads the NEW command's
                                   ACTIVE dmamap (DMA-writeback
                                   onto reused memory)
    ccb->ccb_xa.complete(...)    <- for a CAM command this is
       sili_ata_complete_disk_rw on the REISSUED ccb: xpt_done
       on a CAM ccb that is already owned by the new request
       -> double CAM completion / UAF in the CAM layer
  KKASSERT(ap->ap_active_cnt == 0) in sili_port_hardstop can
  also fire (underflow) on INVARIANTS kernels.