diff mbox series

mpt3sas: Fix reply queue count in non RDPQ mode.

Message ID 20200522103558.5710-1-suganath-prabu.subramani@broadcom.com (mailing list archive)
State Mainlined
Commit f56577e8c7d0f3054f97d1f0d1cbe9a4d179cc47
Headers show
Series mpt3sas: Fix reply queue count in non RDPQ mode. | expand

Commit Message

Suganath Prabu S May 22, 2020, 10:35 a.m. UTC
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@redhat.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Tomas Henzl May 25, 2020, 4:49 p.m. UTC | #1
On 5/22/20 12:35 PM, Suganath Prabu S wrote:
> 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@redhat.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>

I've tested it and this patch fixes the problem

Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Martin K. Petersen May 27, 2020, 2:13 a.m. UTC | #2
On Fri, 22 May 2020 06:35:58 -0400, Suganath Prabu S wrote:

> 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.
> 
> [...]

Applied to 5.8/scsi-queue, thanks!

[1/1] scsi: mpt3sas: Fix reply queue count in non RDPQ mode
      https://git.kernel.org/mkp/scsi/c/f56577e8c7d0
diff mbox series

Patch

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,