DragonFlyBSD Kernel Audit
DF-1282 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mpr/mpr_mapping.c b/sys/dev/raid/mpr/mpr_mapping.c
--- a/sys/dev/raid/mpr/mpr_mapping.c
+++ b/sys/dev/raid/mpr/mpr_mapping.c
@@ -2294,6 +2294,20 @@
 				    MPI2_DRVMAP0_MAPINFO_SLOT_MASK;
 				num_slots >>= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT;
 			}
+			/*
+			 * Bounds-check the firmware-supplied DeviceIndex and slot count
+			 * against the mapping table size before indexing it (DF-1282).
+			 * A malformed DPM entry could otherwise overflow mapping_table[].
+			 */
+			if (dev_idx >= sc->max_devices ||
+			    num_slots > sc->max_devices ||
+			    dev_idx + num_slots > sc->max_devices) {
+				mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: "
+				    "DPM entry %d DeviceIndex %d/%d exceeds max devices "
+				    "%d, skipping.\n", __func__, entry_num, dev_idx,
+				    num_slots, sc->max_devices);
+				break;
+			}
 			enc_idx = sc->num_enc_table_entries;
 			if (enc_idx >= sc->max_enclosures) {
 				mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: "
@@ -2354,6 +2368,13 @@
 			 * mapping table, but check for a corrupt mapping table
 			 * (as described above in Enc/Slot mapping).
 			 */
+			if (dev_idx >= sc->max_devices) {
+				mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: "
+				    "DPM entry %d DeviceIndex %d exceeds max devices "
+				    "%d, skipping.\n", __func__, entry_num, dev_idx,
+				    sc->max_devices);
+				break;
+			}
 			map_idx = dev_idx;
 			mt_entry = &sc->mapping_table[map_idx];
 			if (mt_entry->dpm_entry_num != MPR_DPM_BAD_IDX) {