For non RDPQ mode, Driver allocates a single contiguous block of memory pool for all reply descriptor post queues and passes down a single address in the ReplyDescriptorPostQueueAddress field of the IOC Init Request Message to the firmware. So reply_post queue will have only one entry which holds the address of this single contiguous block of memory pool. So while allocating the reply descriptor post queue pool driver should loop for only one time in non-RDPQ mode. But due to a bug in below patch driver is looping for ioc->reply_queue_count number of times even though reply_post queue's queue depth is only one in non-RDPQ mode. This leads to 'BUG: KASAN: use-after-free in base_alloc_rdpq_dma_pool'. commit 8012209eb26b7819385a6ec6eae4b1d0a0dbe585 ("scsi: mpt3sas: Handle RDPQ DMA allocation in same 4G region") Fix is to loop over only one time while allocating the memory for the reply descriptor post queue in non-RDPQ mode Reported-by: Tomas Henzl <thenzl@xxxxxxxxxx> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@xxxxxxxxxxxx> --- drivers/scsi/mpt3sas/mpt3sas_base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index dc260fe..beaea19 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -4809,6 +4809,7 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) int j = 0; int dma_alloc_count = 0; struct chain_tracker *ct; + int count = ioc->rdpq_array_enable ? ioc->reply_queue_count : 1; dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); @@ -4850,9 +4851,9 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) } if (ioc->reply_post) { - dma_alloc_count = DIV_ROUND_UP(ioc->reply_queue_count, + dma_alloc_count = DIV_ROUND_UP(count, RDPQ_MAX_INDEX_IN_ONE_CHUNK); - for (i = 0; i < ioc->reply_queue_count; i++) { + for (i = 0; i < count; i++) { if (i % RDPQ_MAX_INDEX_IN_ONE_CHUNK == 0 && dma_alloc_count) { if (ioc->reply_post[i].reply_post_free) { @@ -4973,14 +4974,14 @@ base_alloc_rdpq_dma_pool(struct MPT3SAS_ADAPTER *ioc, int sz) * Driver uses limitation of * VENTURA_SERIES to manage INVADER_SERIES as well. */ - dma_alloc_count = DIV_ROUND_UP(ioc->reply_queue_count, + dma_alloc_count = DIV_ROUND_UP(count, RDPQ_MAX_INDEX_IN_ONE_CHUNK); ioc->reply_post_free_dma_pool = dma_pool_create("reply_post_free pool", &ioc->pdev->dev, sz, 16, 0); if (!ioc->reply_post_free_dma_pool) return -ENOMEM; - for (i = 0; i < ioc->reply_queue_count; i++) { + for (i = 0; i < count; i++) { if ((i % RDPQ_MAX_INDEX_IN_ONE_CHUNK == 0) && dma_alloc_count) { ioc->reply_post[i].reply_post_free = dma_pool_alloc(ioc->reply_post_free_dma_pool, -- 1.8.3.1