mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 03:20:25 -04:00
staging: comedi: ni_labpc: fix possible double-free of dma_buffer
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@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
c383e2d6da
commit
725a70d8a6
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user