diff --git a/sys/dev/raid/mfi/mfi.c b/sys/dev/raid/mfi/mfi.c --- a/sys/dev/raid/mfi/mfi.c +++ b/sys/dev/raid/mfi/mfi.c @@ -2724,12 +2724,25 @@ static int mfi_stp_cmd(struct mfi_softc *sc, struct mfi_command *cm,caddr_t arg) { - uint8_t i; + int i; struct mfi_ioc_packet *ioc; ioc = (struct mfi_ioc_packet *)arg; int sge_size, error; struct megasas_sge *kern_sge; + /* + * The DMA bounce-buffer arrays (mfi_kbuff_arr_dmat/dmamap/busaddr) and the + * STP frame SGL arrays are only sized for 2 entries (mfivar.h / mfireg.h). + * Reject requests with more SGEs than we have storage for, otherwise the + * loop below writes past them into the surrounding mfi_softc fields. + */ + if (ioc->mfi_sge_count > + (sizeof(sc->mfi_kbuff_arr_dmat) / sizeof(sc->mfi_kbuff_arr_dmat[0]))) { + device_printf(sc->mfi_dev, "mfi_stp_cmd: too many SGEs (%u)\n", + ioc->mfi_sge_count); + return (EINVAL); + } + memset(sc->kbuff_arr, 0, sizeof(sc->kbuff_arr)); kern_sge =(struct megasas_sge *) ((uintptr_t)cm->cm_frame + ioc->mfi_sgl_off); cm->cm_frame->header.sg_count = ioc->mfi_sge_count;