From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 480B138DC43 for ; Fri, 11 Sep 2026 15:05:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789139134; cv=none; b=YaqhAedmrC3+ZjSzKjUp+GiUq6vjYTVkj1iTnhGPWh2j7on6IqRAHHvNloUQmz91sUTC0Go9HdKF1NMMHXnJTcWImulq6ssTd7NMxKWWTL6dd40KIimyaItjUFATKz7KKGozcS1KSLxnfZcnXg4s2rfxOkxol5LQVV2LFw7nT7Q= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789139134; c=relaxed/simple; bh=DqlSpcKpwRiFfMrXKJ/DuFczPqJIxeLtma5CeVNaEk0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h/JItheClljJKufdTruH6vvg1C7uanwsT+aMR7UrR8/W3AMcotzmfpHFqPrWKwyH2tl/qaWEyBqEmPiS55sRj6cr8+bfIuBebaendOLhpx0u3NcsZm73WniS8HX/8Z3QC+B/VM1/8GN3yQLM1boWQPqYz71NKE9jPFYrH5Qb/Q8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dA46z02M; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dA46z02M" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 664A91F000FF; Fri, 11 Sep 2026 15:05:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789139133; bh=a0cpS7NzOz/3G8T9YZ0BNy5jlRdwGX+uOizVj1Ldl6M=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=dA46z02M7BQvz+HZOZPFD3bPGvJK5YAMDCh6sBloymnWWvFW9wvwP5GIZPF2gR17w pGkyQZxnSkL3e6daq0NUG9irphtyDwwi5CmVj8rhn/tTXhBilQYMz9JTZm+7b+vIAk Y8W5qJ5DWPYW7OnshkNsA66K23RYLqe1CWbbJUynkncs43Hct8J7rn8UzCBY6nnGEp 4Q0TFjAccEc60i8Gdmu/yilV/6k812uLbfxPubt4AQnOm9XIg0UcP65MX60/ce11L2 psRryL+eNN6U+jySes/7m0knLk+OSCOZrKx+qdQ3o8NoXzWtK9t/sSi9Ww1723kRHe am8ODHU0tfcNQ== From: Sasha Levin To: stable@vger.kernel.org Cc: Nilesh Javali , Hannes Reinecke , "Martin K. Petersen (Oracle)" , Sasha Levin Subject: [PATCH 6.12.y 1/2] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Date: Fri, 11 Sep 2026 11:05:29 -0400 Message-ID: <20260911150530.1032073-1-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <2026090919-divided-onion-9b49@gregkh> References: <2026090919-divided-onion-9b49@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Nilesh Javali [ Upstream commit 34a40e0dff940ac5eba494a69b553ea571e24873 ] qla25xx_free_req_que() and qla25xx_free_rsp_que() have two pre-existing bugs exposed on the error path of qla25xx_create_{req,rsp}_que(): 1. When dma_alloc_coherent() fails during queue creation, the error path calls the free function with req->ring / rsp->ring still NULL (from kzalloc). The unconditional dma_free_coherent() with a NULL cpu_addr is undefined behavior and can panic. 2. The free functions clear req_qid_map / rsp_qid_map under vport_lock, but the create functions protect the same bitmaps with mq_lock. This provides no mutual exclusion. Additionally, the create error path clears the bit and releases mq_lock before calling the free function, creating a window where another thread can allocate the same que_id and have its ha->req_q_map entry clobbered by the subsequent lockless NULL assignment in the free function. Fix by: - Guarding dma_free_coherent() with a NULL check on the ring pointer. - Using mq_lock (the lock held by all creators) in the free functions to atomically NULL the map entry and clear the bitmap bit. - Removing the now-redundant clear_bit blocks from the create error paths since the free functions handle it atomically. Signed-off-by: Nilesh Javali Reviewed-by: Hannes Reinecke Link: https://patch.msgid.link/20260723050413.3897522-41-njavali@marvell.com Signed-off-by: Martin K. Petersen (Oracle) Backport adaptation for the stable tree: the 29xx IOCB size-selection helpers are absent, and queue creation still allocates fixed-size entries. Initialize the local req_entry_size and rsp_entry_size values with sizeof(request_t) and sizeof(response_t), respectively, so DMA freeing continues to match allocation without adding helper functions or 29xx support. Retain all NULL-ring guards, mq_lock protection, and removal of the premature bitmap clears. Keep the response-ring cleanup layout used by upstream so target commit 19788a55cab61d78e33e0914a5a31d27843e8a4a applies unchanged. Stable-dep-of: 19788a55cab6 ("scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown") Signed-off-by: Sasha Levin --- drivers/scsi/qla2xxx/qla_mid.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 9946899dd83b8..61570f032a8ac 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -574,16 +574,19 @@ qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req) { struct qla_hw_data *ha = vha->hw; uint16_t que_id = req->id; + size_t req_entry_size = sizeof(request_t); - dma_free_coherent(&ha->pdev->dev, (req->length + 1) * - sizeof(request_t), req->ring, req->dma); + if (req->ring) + dma_free_coherent(&ha->pdev->dev, + (req->length + 1) * req_entry_size, + req->ring, req->dma); req->ring = NULL; req->dma = 0; if (que_id) { + mutex_lock(&ha->mq_lock); ha->req_q_map[que_id] = NULL; - mutex_lock(&ha->vport_lock); clear_bit(que_id, ha->req_qid_map); - mutex_unlock(&ha->vport_lock); + mutex_unlock(&ha->mq_lock); } kfree(req->outstanding_cmds); kfree(req); @@ -594,6 +597,7 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) { struct qla_hw_data *ha = vha->hw; uint16_t que_id = rsp->id; + size_t rsp_entry_size = sizeof(response_t); if (rsp->msix && rsp->msix->have_irq) { free_irq(rsp->msix->vector, rsp->msix->handle); @@ -601,15 +605,18 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) rsp->msix->in_use = 0; rsp->msix->handle = NULL; } - dma_free_coherent(&ha->pdev->dev, (rsp->length + 1) * - sizeof(response_t), rsp->ring, rsp->dma); + + if (rsp->ring) + dma_free_coherent(&ha->pdev->dev, + (rsp->length + 1) * rsp_entry_size, + rsp->ring, rsp->dma); rsp->ring = NULL; rsp->dma = 0; if (que_id) { + mutex_lock(&ha->mq_lock); ha->rsp_q_map[que_id] = NULL; - mutex_lock(&ha->vport_lock); clear_bit(que_id, ha->rsp_qid_map); - mutex_unlock(&ha->vport_lock); + mutex_unlock(&ha->mq_lock); } kfree(rsp); } @@ -794,9 +801,6 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, if (ret != QLA_SUCCESS) { ql_log(ql_log_fatal, base_vha, 0x00df, "%s failed.\n", __func__); - mutex_lock(&ha->mq_lock); - clear_bit(que_id, ha->req_qid_map); - mutex_unlock(&ha->mq_lock); goto que_failed; } vha->flags.qpairs_req_created = 1; @@ -908,9 +912,6 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, if (ret != QLA_SUCCESS) { ql_log(ql_log_fatal, base_vha, 0x00e7, "%s failed.\n", __func__); - mutex_lock(&ha->mq_lock); - clear_bit(que_id, ha->rsp_qid_map); - mutex_unlock(&ha->mq_lock); goto que_failed; } vha->flags.qpairs_rsp_created = 1; -- 2.53.0