summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorNilesh Javali <njavali@marvell.com>2026-07-30 21:28:21 +0530
committerMartin K. Petersen (Oracle) <mkp@kernel.org>2026-08-06 16:41:10 -0400
commitdeb8abde83a799d2501f3977f6d6051000253f5e (patch)
treeed23324bfb26b467ffd1cf8b13e97e3b8f9d8439 /drivers/scsi
parentca6d880d6c70cb7946e7b3e05d7285f271b6d99e (diff)
downloadlinux-next-deb8abde83a799d2501f3977f6d6051000253f5e.tar.gz
linux-next-deb8abde83a799d2501f3977f6d6051000253f5e.zip
scsi: qla2xxx: Avoid req_q_map double-read in qla2x00_error_entry()
qla2x00_error_entry() reads ha->req_q_map[que] twice: once for the NULL check and again when assigning it to req. The map slot is cleared by qla25xx_free_req_que() (ha->req_q_map[que_id] = NULL under mq_lock) during queue teardown, while the response-queue interrupt that drives qla2x00_error_entry() is still registered (the IRQ is released later in qla25xx_free_rsp_que()). If the slot is set to NULL between the two reads, req becomes NULL and is dereferenced. Read the slot once into req and NULL-check the local before use. mq_lock is a mutex and cannot be taken from interrupt context, so the single read plus local check is the appropriate fix for the reported NULL dereference. Fixes: a6fe35c052c4 ("[SCSI] qla2xxx: Avoid invalid request queue dereference for bad response packets.") Cc: stable@vger.kernel.org Reported-by: Sashiko <sashiko-dev@google.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://patch.msgid.link/20260730155838.2119230-17-njavali@marvell.com Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 02f88a79964a..ddcfccfaef9c 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3928,10 +3928,12 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
"iocb type %xh with error status %xh, handle %xh, rspq id %d\n",
pkt->entry_type, pkt->entry_status, pkt->handle, rsp->id);
- if (que >= ha->max_req_queues || !ha->req_q_map[que])
+ if (que >= ha->max_req_queues)
goto fatal;
req = ha->req_q_map[que];
+ if (!req)
+ goto fatal;
if (pkt->entry_status & RF_BUSY)
res = DID_BUS_BUSY << 16;