DF-4869 / fix.diff
--- 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; } } |