DF-3962 / trigger.c
/* * DF-3962 trigger sketch โ mvfrey CCB-timeout callout races the IRQ handler * ======================================================================== * hptiop_post_req_mvfrey() arms a 20 s per-CCB timeout: * * hptiop.c:2647 if (req->header.type == IOP_REQUEST_TYPE_SCSI_COMMAND) { * hptiop.c:2648 callout_reset(ccb->ccb_h.timeout_ch, 20 * hz, * hptiop.c:2649 hptiop_reset_adapter, hba); * * The callout fires hptiop_reset_adapter(hba) (hptiop.c:2244-2250) which runs * hptiop_send_sync_msg() -> hba->ops->iop_intr(hba) (hptiop.c:899-906) WITHOUT * taking hba->lock, while the hard interrupt path hptiop_pci_intr() * (hptiop.c:2163-2169) runs the very same iop_intr holding the lock. * * hptiop_intr_mvfrey() (hptiop.c:782-795) drains the shared outlist using the * NON-atomic hba->u.mvfrey.outlist_rptr: * do { cptr = *outlist_cptr & 0xff; * while (rptr != cptr) { rptr++; _tag = outlist[rptr].val; * hptiop_request_callback_mvfrey(hba,_tag); } } * while (cptr != (*outlist_cptr & 0xff)); * * Two CPUs executing this concurrently (callout on CPU0 unlocked, IRQ on CPU1 * locked) both observe rptr != cptr, both read the SAME outlist entry, both * call hptiop_request_callback_mvfrey(_tag) for the same tag -> * srb = hba->srb[(_tag>>4)&0xff] completed TWICE: * - hptiop_free_srb(hba, srb) twice -> srb on freelist twice * -> two live CCBs share one srb -> cross-command corruption * - xpt_done(ccb) twice -> CAM UAF on the ccb * - bus_dmamap_unload(dma_map) twice * * Second leg: the timed-out CCB itself is NEVER completed by the timeout * handler (the callout arg is hba, not the ccb) โ if the reset does not make * the firmware complete the request, the ccb hangs forever (CAM wedge). * * Third leg: hptiop_send_sync_msg(RESET, 60000) busy-loops DELAY(1000) up to * 60 s inside softclock โ starves the callout CPU, trips watchdogs. * * Compare the sibling HighPoint drivers, whose timeout handlers DO lock: * sys/dev/raid/hptmv/entry.c:2626-2633 hpt_timeout(): lock_driver(); fResetVBus() * sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:530-532 * * Trigger on hardware: stall one mvfrey device (RR 43xx/45xx) โ e.g. saturate * it and hot-unplug/expel it, or let the MCU wedge โ so that a SCSI command * outruns its 20 s timeout while later completions still arrive. */ int main(void) { return 0; } /* informational sketch โ see VERDICT.md */ |