Skip to content

Commit 8e45183

Browse files
Ranjan Kumarmartinkpetersen
authored andcommitted
scsi: mpi3mr: Bad drive in topology results kernel crash
When the SAS Transport Layer support is enabled and a device exposed to the OS by the driver fails INQUIRY commands, the driver frees up the memory allocated for an internal HBA port data structure. However, in some places, the reference to the freed memory is not cleared. When the firmware sends the Device Info change event for the same device again, the freed memory is accessed and that leads to memory corruption and OS crash. Signed-off-by: Ranjan Kumar <[email protected]> Signed-off-by: Sreekanth Reddy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 4f297e8 commit 8e45183

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

drivers/scsi/mpi3mr/mpi3mr_transport.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,15 +2358,16 @@ int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
23582358
tgtdev->host_exposed = 1;
23592359
if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle,
23602360
sas_address_parent, hba_port)) {
2361-
tgtdev->host_exposed = 0;
23622361
retval = -1;
2363-
} else if ((!tgtdev->starget)) {
2364-
if (!mrioc->is_driver_loading)
2362+
} else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) {
23652363
mpi3mr_sas_port_remove(mrioc, sas_address,
23662364
sas_address_parent, hba_port);
2367-
tgtdev->host_exposed = 0;
23682365
retval = -1;
23692366
}
2367+
if (retval) {
2368+
tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
2369+
tgtdev->host_exposed = 0;
2370+
}
23702371
return retval;
23712372
}
23722373

@@ -2395,6 +2396,7 @@ void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc,
23952396
mpi3mr_sas_port_remove(mrioc, sas_address, sas_address_parent,
23962397
hba_port);
23972398
tgtdev->host_exposed = 0;
2399+
tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
23982400
}
23992401

24002402
/**
@@ -2451,7 +2453,7 @@ static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *
24512453

24522454
tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
24532455
rphy->identify.sas_address, rphy);
2454-
if (tgtdev) {
2456+
if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) {
24552457
port_id =
24562458
tgtdev->dev_spec.sas_sata_inf.hba_port->port_id;
24572459
mpi3mr_tgtdev_put(tgtdev);

0 commit comments

Comments
 (0)