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

From: Wentao Liang

Date: Thu Sep 17 2026 - 11:15:42 EST


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@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
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