diff options
| -rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_os.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 9aeec6146acb..6a80b784200b 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -2827,12 +2827,28 @@ static void mpi3mr_sastopochg_evt_th(struct mpi3mr_ioc *mrioc, struct mpi3_event_data_sas_topology_change_list *topo_evt = (struct mpi3_event_data_sas_topology_change_list *)event_reply->event_data; int i; - u16 handle; - u8 reason_code; + u16 handle, avail_len; + u8 reason_code, max_entries, num_entries; struct mpi3mr_tgt_dev *tgtdev = NULL; struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL; - for (i = 0; i < topo_evt->num_entries; i++) { + avail_len = event_reply->event_data_length * 4; + if (avail_len < offsetof(struct mpi3_event_data_sas_topology_change_list, phy_entry)) { + ioc_err(mrioc, "SAS topology event: event data too small (%u bytes)\n", + avail_len); + return; + } + max_entries = (avail_len - + offsetof(struct mpi3_event_data_sas_topology_change_list, phy_entry)) / + sizeof(struct mpi3_event_sas_topo_phy_entry); + num_entries = topo_evt->num_entries; + if (num_entries > max_entries) { + ioc_err(mrioc, "SAS topology event: num_entries(%d) exceeds max(%d)\n", + num_entries, max_entries); + return; + } + + for (i = 0; i < num_entries; i++) { handle = le16_to_cpu(topo_evt->phy_entry[i].attached_dev_handle); if (!handle) continue; |
