DragonFlyBSD Kernel Audit
DF-1557 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mps/mps_config.c b/sys/dev/raid/mps/mps_config.c
--- a/sys/dev/raid/mps/mps_config.c
+++ b/sys/dev/raid/mps/mps_config.c
@@ -459,6 +459,18 @@
 		 */
 		pRVPD = (pMpi2RaidVol0PhysDisk_t)&raid_vol_pg0->PhysDisk;
 		for (index = 0; index < raid_vol_pg0->NumPhysDisks; index++) {
+			/* DF-1557: PhysDiskMap is an untrusted U8 from firmware and indexes
+			 * DD_column_map[MPS_MAX_DISKS_IN_VOL]; it must be bounds-checked,
+			 * since DD_column_map is the final field of struct mps_softc and any
+			 * index >= MPS_MAX_DISKS_IN_VOL writes past the softc allocation.
+			 */
+			if (pRVPD->PhysDiskMap >= MPS_MAX_DISKS_IN_VOL) {
+				mps_dprint(sc, MPS_FAULT,
+				    "PhysDiskMap %u out of range in WD volume. "
+				    "Direct Drive I/O will not be used.\n",
+				    pRVPD->PhysDiskMap);
+				goto out;
+			}
 			sc->DD_column_map[pRVPD->PhysDiskMap].phys_disk_num =
 			    pRVPD->PhysDiskNum;
 			pRVPD++;