[PATCH] scsi: arcmsr: fix NULL deref on dma_alloc_coherent() failure in arcmsr_alloc_xor_buffer()
Ivy Lopez <[email protected]> Thu, 6 Aug 2026 23:25:43 -0600
| Newsgroups | gmane.linux.scsi,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
arcmsr_alloc_xor_buffer() does not check the return value of the initial dma_alloc_coherent() call before using it. If the allocation fails, the code performs pointer arithmetic on the NULL base (computing pXorPhys and pXorVirt) and later unconditionally dereferences it through pRamBuf to write hrbSignature and other fields, causing a NULL pointer dereference. Additionally, acb->xor_mega is set unconditionally before the allocation attempt, based only on firmware status bits. If the allocation fails, acb->xor_mega remains nonzero, so the later cleanup path in arcmsr_free_ccb_pool() and the message-config code in arcmsr_iop_confirm() will still enter their "if (acb->xor_mega)" branches and dereference the never-set acb->xorVirt/acb->xorPhys, a second NULL pointer dereference on the allocation failure path. Fix this by checking the initial dma_alloc_coherent() result and, on failure, resetting acb->xor_mega to 0 before returning -ENOMEM, so that no code path treats the XOR buffer as present when it was never allocated. Found by static analysis; no hardware reproducer. Signed-off-by: Ivy Lopez <[email protected]> Cc: ching Huang <[email protected]> --- drivers/scsi/arcmsr/arcmsr_hba.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 8aa948f06cac..40407b281839 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -771,6 +771,12 @@ static int arcmsr_alloc_xor_buffer(struct AdapterControlBlock *acb) (sizeof(struct XorHandle) * acb->xor_mega); dma_coherent = dma_alloc_coherent(&pdev->dev, acb->init2cfg_size, &dma_coherent_handle, GFP_KERNEL); + if (!dma_coherent) { + pr_info("arcmsr%d: alloc init2cfg buffer failed\n", + acb->host->host_no); + acb->xor_mega = 0; + return -ENOMEM; + } acb->xorVirt = dma_coherent; acb->xorPhys = dma_coherent_handle; pXorPhys = (struct Xor_sg *)((unsigned long)dma_coherent + -- 2.55.0