[PATCH 01/12] staging: comedi: ni_labpc: fix possible double-free of dma_buffer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If `labpc_attach()` allocates memory for `devpriv->dma_buffer` but fails
to request a DMA channel, it frees `devpriv->dma_buffer` but leaves the
pointer set.  Later, `labpc_detach()` frees `devpriv->dma_buffer` again,
which means it has been freed twice in this case.

Fix it by only setting `devpriv->dma_buffer` in `labpc_attach()` if the
DMA channel was requested successfully.

Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx>
---
 drivers/staging/comedi/drivers/ni_labpc.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index f161e70..0783d65 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -1712,13 +1712,15 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 #ifdef CONFIG_ISA_DMA_API
 	if (dev->irq && (dma_chan == 1 || dma_chan == 3)) {
-		devpriv->dma_buffer = kmalloc(dma_buffer_size,
-					      GFP_KERNEL | GFP_DMA);
-		if (devpriv->dma_buffer) {
+		void *dma_buffer = kmalloc(dma_buffer_size,
+					   GFP_KERNEL | GFP_DMA);
+
+		if (dma_buffer) {
 			ret = request_dma(dma_chan, dev->board_name);
 			if (ret == 0) {
 				unsigned long dma_flags;
 
+				devpriv->dma_buffer = dma_buffer;
 				devpriv->dma_chan = dma_chan;
 				devpriv->dma_addr =
 					virt_to_bus(devpriv->dma_buffer);
@@ -1728,7 +1730,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
 				release_dma_lock(dma_flags);
 			} else {
-				kfree(devpriv->dma_buffer);
+				kfree(dma_buffer);
 			}
 		}
 	}
-- 
1.8.2.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux