[PATCH] scsi: mpi3mr: Fix tgt_dev reference leak in mpi3mr_target_alloc()

Wentao Liang posted 1 patch 1 week ago
drivers/scsi/mpi3mr/mpi3mr_os.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
[PATCH] scsi: mpi3mr: Fix tgt_dev reference leak in mpi3mr_target_alloc()
Posted by Wentao Liang 1 week ago
The target device reference taken by __mpi3mr_get_tgtdev_by_perst_id()
and __mpi3mr_get_tgtdev_by_addr_and_rphy() is handed over to
scsi_tgt_priv_data->tgt_dev on the success path. When the target is
hidden or does not match the expected device type, the function returns
-ENXIO without dropping that reference, so it is leaked.

Drop the reference on both error paths.

Fixes: 626665e9c38d ("scsi: mpi3mr: Get target object based on rphy")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/scsi/mpi3mr/mpi3mr_os.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index 5ff5720f2491..3d75ae422354 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -4965,8 +4965,11 @@ static int mpi3mr_target_alloc(struct scsi_target *starget)
 			scsi_tgt_priv_data->wslen = tgt_dev->wslen;
 			if (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_VD)
 				scsi_tgt_priv_data->throttle_group = tgt_dev->dev_spec.vd_inf.tg;
-		} else
+		} else {
+			if (tgt_dev)
+				mpi3mr_tgtdev_put(tgt_dev);
 			retval = -ENXIO;
+		}
 	} else if (mrioc->sas_transport_enabled && !starget->channel) {
 		rphy = dev_to_rphy(starget->dev.parent);
 		tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
@@ -4983,8 +4986,11 @@ static int mpi3mr_target_alloc(struct scsi_target *starget)
 			tgt_dev->starget = starget;
 			atomic_set(&scsi_tgt_priv_data->block_io, 0);
 			retval = 0;
-		} else
+		} else {
+			if (tgt_dev)
+				mpi3mr_tgtdev_put(tgt_dev);
 			retval = -ENXIO;
+		}
 	}
 	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
 
-- 
2.34.1