summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt3sas
diff options
context:
space:
mode:
authorJoe Lawrence <joe.lawrence@stratus.com>2016-05-25 15:14:28 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-07-12 23:16:31 -0400
commit87aa95d4bb77613acaed9724efe07dde9e9bacd7 (patch)
tree292745673bb9c5589b8c90678e105c592ef2d60c /drivers/scsi/mpt3sas
parent87ee3ab928dc4a3723005c5b553775e9acf479c1 (diff)
downloadlinux-87aa95d4bb77613acaed9724efe07dde9e9bacd7.tar.bz2
mpt3sas: set num_phys after allocating phy[] space
In _scsih_sas_host_add, the number of HBA phys are determined and then later used to allocate an array of struct _sas_phy's. If the routine sets ioc->sas_hba.num_phys, but then fails to allocate the ioc->sas_hba.phy array (by kcalloc error or other intermediate error/exit path), ioc->sas_hba is left in a dangerous state: all readers of ioc->sas_hba.phy[] do so by indexing it from 0..ioc->sas_hba.num_phys without checking that the space was ever allocated. Modify _scsih_sas_host_add to set ioc->sas_hba.num_phys only after successfully allocating ioc->sas_hba.phy[]. Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com> Acked-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/mpt3sas')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_scsih.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6bff13e7afc7..cd6be7be0c5b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4903,13 +4903,22 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc)
u16 ioc_status;
u16 sz;
u8 device_missing_delay;
+ u8 num_phys;
- mpt3sas_config_get_number_hba_phys(ioc, &ioc->sas_hba.num_phys);
- if (!ioc->sas_hba.num_phys) {
+ mpt3sas_config_get_number_hba_phys(ioc, &num_phys);
+ if (!num_phys) {
pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
return;
}
+ ioc->sas_hba.phy = kcalloc(num_phys,
+ sizeof(struct _sas_phy), GFP_KERNEL);
+ if (!ioc->sas_hba.phy) {
+ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+ ioc->name, __FILE__, __LINE__, __func__);
+ goto out;
+ }
+ ioc->sas_hba.num_phys = num_phys;
/* sas_iounit page 0 */
sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
@@ -4969,13 +4978,6 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc)
MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev;
- ioc->sas_hba.phy = kcalloc(ioc->sas_hba.num_phys,
- sizeof(struct _sas_phy), GFP_KERNEL);
- if (!ioc->sas_hba.phy) {
- pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
- ioc->name, __FILE__, __LINE__, __func__);
- goto out;
- }
for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
i))) {