[PATCH OLK-6.6] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking
From: Nilesh Javali <njavali@marvell.com> stable inclusion from stable-v6.6.160 commit 2e6f60adf609c77e828f64e0cd371920bef91c12 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20146 Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/... -------------------------------- [ 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 <njavali@marvell.com> Reviewed-by: Hannes Reinecke <hare@kernel.org> Link: https://patch.msgid.link/20260723050413.3897522-41-njavali@marvell.com Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org> 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 <sashal@kernel.org> Conflicts: drivers/scsi/qla2xxx/qla_mid.c [Simple context conflicts.] Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/scsi/qla2xxx/qla_mid.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 4029b7942e21..86c0217d1763 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -572,30 +572,34 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) static void 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); } static void 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); rsp->msix->have_irq = 0; rsp->msix->in_use = 0; @@ -604,19 +608,21 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) /* Flush any queued response work before freeing the queue/qpair. */ if (rsp->qpair && ha->wq) cancel_work_sync(&rsp->qpair->q_work); - 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); } int @@ -797,13 +803,10 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, if (startqp) { ret = qla25xx_init_req_que(base_vha, req); 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; } @@ -911,13 +914,10 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, if (startqp) { ret = qla25xx_init_rsp_que(base_vha, rsp); 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; } rsp->req = NULL; -- 2.52.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/30042 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/HJ2... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/30042 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/HJ2...
participants (2)
-
patchwork bot -
Zizhi Wo