__mpi3mr_get_tgtdev_by_addr_and_rphy() takes a reference on the target device, but it is only dropped when the device has a valid hba_port. When the hba_port has already been cleared because the device is gone, the function returns without releasing the reference and the target device is leaked. Release the reference whenever the lookup succeeds. Fixes: 8e45183978d6 ("scsi: mpi3mr: Bad drive in topology results kernel crash") Cc: stable@vger.kernel.org Signed-off-by: Wentao Liang --- drivers/scsi/mpi3mr/mpi3mr_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c index 240f67a8e2e3..a95c9352e859 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c @@ -2499,11 +2499,11 @@ static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy * tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, rphy->identify.sas_address, rphy); - if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) { + if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) port_id = tgtdev->dev_spec.sas_sata_inf.hba_port->port_id; + if (tgtdev) mpi3mr_tgtdev_put(tgtdev); - } spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); } return port_id; -- 2.34.1