DragonFlyBSD Kernel Audit
DF-1259 / fix.diff
← back to finding ↓ download raw
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;