DragonFlyBSD Kernel Audit
DF-1474 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mpr/mpr_sas_lsi.c b/sys/dev/raid/mpr/mpr_sas_lsi.c
--- a/sys/dev/raid/mpr/mpr_sas_lsi.c
+++ b/sys/dev/raid/mpr/mpr_sas_lsi.c
@@ -85,6 +85,7 @@
 struct mpr_fw_event_work {
 	u16			event;
 	void			*event_data;
+	u16			event_data_sz;
 	TAILQ_ENTRY(mpr_fw_event_work)	ev_link;
 };
 
@@ -146,6 +147,7 @@
 		return;
 	}
 	sz = le16toh(event->EventDataLength) * 4;
+	fw_event->event_data_sz = sz;
 	fw_event->event_data = kmalloc(sz, M_MPR, M_ZERO|M_NOWAIT);
 	if (!fw_event->event_data) {
 		kprintf("%s: allocate failed for event_data\n", __func__);
@@ -213,7 +215,12 @@
 
 		mpr_mapping_topology_change_event(sc, fw_event->event_data);
 
-		for (i = 0; i < data->NumEntries; i++) {
+		for (i = 0;
+		    i < data->NumEntries &&
+		    i * sizeof(MPI2_EVENT_SAS_TOPO_PHY_ENTRY) +
+			offsetof(MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST, PHY) <=
+		    fw_event->event_data_sz;
+		    i++) {
 			phy = &data->PHY[i];
 			switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) {
 			case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
@@ -291,7 +298,11 @@
 		    element->VolDevHandle);
 
 		mpr_mapping_ir_config_change_event(sc, event_data);
-		for (i = 0; i < event_data->NumElements; i++, element++) {
+		for (i = 0;
+		    i < event_data->NumElements &&
+		    i * sizeof(Mpi2EventIrConfigElement_t) <=
+		    fw_event->event_data_sz;
+		    i++, element++) {
 			reason = element->ReasonCode;
 			elementType = le16toh(element->ElementFlags) &
 			    MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK;