[PATCH] scsi: arcmsr: fix DMA memory and IO queue leak on arcmsr_alloc_ccb_pool() failure

Ivy Lopez <[email protected]>
Newsgroups org.kernel.vger.linux-scsi,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
If arcmsr_alloc_ccb_pool() fails in arcmsr_probe(), the error path
jumps directly to unmap_pci_region, bypassing the free_ccb_pool
label entirely. This leaks the CCB pool DMA allocation
(acb->dma_coherent) whenever arcmsr_alloc_ccb_pool() fails after
successfully allocating it, e.g. when the later
arcmsr_alloc_xor_buffer() call fails.

For ACB_ADAPTER_TYPE_F adapters specifically, the IO queue allocated
earlier by arcmsr_alloc_io_queue() is also never freed on this path:
other adapter types free their IO queue before calling
arcmsr_alloc_ccb_pool() (since its space is folded into the CCB
pool's own allocation), but type F does not, so it remains allocated
and leaked if arcmsr_alloc_ccb_pool() subsequently fails.

Fix this by routing arcmsr_alloc_ccb_pool() failure through the
existing free_ccb_pool label, and explicitly freeing the IO queue
for type F adapters beforehand. arcmsr_free_ccb_pool() is safe to
call here regardless of how far arcmsr_alloc_ccb_pool() got:
dma_free_coherent() is a no-op on a NULL address, and acb is
zero-initialized via scsi_host_alloc()'s kzalloc(), so
acb->dma_coherent and acb->xor_mega are both safely zero if
arcmsr_alloc_ccb_pool() failed before setting them.

Found via review feedback on a related fix (commit afa04c2998e4,
"scsi: arcmsr: fix NULL deref on dma_alloc_coherent() failure in
arcmsr_alloc_xor_buffer()").

Signed-off-by: Ivy Lopez <[email protected]>
Cc: ching Huang <[email protected]>
---
 drivers/scsi/arcmsr/arcmsr_hba.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 40407b281839..d8e56d7b1906 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1150,7 +1150,9 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		arcmsr_free_io_queue(acb);
 	error = arcmsr_alloc_ccb_pool(acb);
 	if(error){
-		goto unmap_pci_region;
+		if (acb->adapter_type == ACB_ADAPTER_TYPE_F)
+			arcmsr_free_io_queue(acb);
+		goto free_ccb_pool;
 	}
 	error = scsi_add_host(host, &pdev->dev);
 	if(error){
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.