⬢ DragonFlyBSD Kernel Audit
DF-4869 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mps/mps_table.c
+++ b/sys/dev/raid/mps/mps_table.c
@@ -66,11 +66,12 @@ char *
 mps_describe_table(struct mps_table_lookup *table, u_int code)
 {
 	int i;
 
 	for (i = 0; table[i].string != NULL; i++) {
 		if (table[i].code == code)
 			return(table[i].string);
 	}
-	return(table[i+1].string);
+	/* do not rely on every table carrying an entry past the sentinel */
+	return ("Unknown");
 }
@@ -315,13 +316,14 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
 	{
 		MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
 		MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
-		int i, phynum;
+		int i, phynum, nent;
 
 		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
 		    &event->EventData;
 		MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
 		MPS_EVENTFIELD(sc, data, ExpanderDevHandle, 0x%x);
 		MPS_EVENTFIELD(sc, data, NumPhys, %d);
 		MPS_EVENTFIELD(sc, data, NumEntries, %d);
 		MPS_EVENTFIELD(sc, data, StartPhyNum, %d);
 		mps_dprint_field(sc, MPS_EVENT, "ExpStatus: %s (0x%x)\n",
 		    mps_describe_table(mps_sastopo_exp, data->ExpStatus),
 		    data->ExpStatus);
 		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
-		for (i = 0; i < data->NumEntries; i++) {
+		/* bound the PHY walk by the event data actually delivered */
+		nent = ((int)le16toh(event->EventDataLength) * 4 -
+		    __offsetof(MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST, PHY)) /
+		    (int)sizeof(data->PHY[0]);
+		if (nent > data->NumEntries)
+			nent = data->NumEntries;
+		if (nent < 0)
+			nent = 0;
+		for (i = 0; i < nent; i++) {
 			phy = &data->PHY[i];
 			phynum = data->StartPhyNum + i;
 			mps_dprint_field(sc, MPS_EVENT,
 			    "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
 			    phy->AttachedDevHandle);
 			mps_dprint_field(sc, MPS_EVENT,
 			    "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
 			    mps_describe_table(mps_linkrate_names,
 			    (phy->LinkRate >> 4) & 0xf), phy->LinkRate);
 			mps_dprint_field(sc,MPS_EVENT,"PHY[%d].PhyStatus: %s\n",
 			    phynum, mps_describe_table(mps_phystatus_names,
 			    phy->PhyStatus));
 		}
 		break;
 	}
@@ -363,6 +365,7 @@ mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 		mps_dprint_field(sc, MPS_EVENT, "SASAddress: 0x%jx\n",
 		    mps_to_u64(&data->SASAddress));
 	}
+	break;
 	default:
 		break;
 	}
 }