DF-1242 / fix.diff
diff --git a/sys/dev/raid/mrsas/mrsas.c b/sys/dev/raid/mrsas/mrsas.c index 38a2742c..55fbf36b 100644 --- a/sys/dev/raid/mrsas/mrsas.c +++ b/sys/dev/raid/mrsas/mrsas.c @@ -1267,6 +1267,30 @@ static int mrsas_complete_cmd(struct mrsas_softc *sc) while((desc_val.u.low != 0xFFFFFFFF) && (desc_val.u.high != 0xFFFFFFFF)) { smid = reply_desc->SMID; + /* + * SMID comes from DMA (firmware). smid==0 yields index -1; smid + * above max_fw_cmds is a wild OOB into mpt_cmd_list[]. Both + * produce a garbage cmd_mpt whose deref (io_request, ccb_ptr, + * sync_cmd_idx) corrupts or crashes the kernel. Drop the entry. + */ + if (smid == 0 || smid > sc->max_fw_cmds) { + device_printf(sc->mrsas_dev, + "invalid SMID %u (max %u), dropping reply\n", + smid, sc->max_fw_cmds); + sc->last_reply_idx++; + if (sc->last_reply_idx >= sc->reply_q_depth) + sc->last_reply_idx = 0; + desc->Words = ~((uint64_t)0x00); + if (!sc->last_reply_idx) + desc = sc->reply_desc_mem; + else + desc++; + reply_desc = (MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc; + desc_val.word = desc->Words; + reply_descript_type = + reply_desc->ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; + continue; + } cmd_mpt = sc->mpt_cmd_list[smid -1]; scsi_io_req = (MRSAS_RAID_SCSI_IO_REQUEST *)cmd_mpt->io_request; |