2008-03-22 18:32:46

by Christian Casteyde

[permalink] [raw]
Subject: [PATCH 2.6.25-rc6] b43/dma.c: fix DMA unmapping in DMA ring error path

This fixes a DMA mapping leak in error path of the b43_setup_dmaring function.
When DMA mapping fails because of device mask preventing the allocated DMA
zone from being used, the mapping should be reversed before the second try with GFP_DMA.

Signed-off-by: Christian Casteyde <[email protected]>

---
--- linux-2.6.25.old/drivers/net/wireless/b43/dma.c 2008-03-22 17:28:52.000000000 +0100
+++ linux-2.6.25/drivers/net/wireless/b43/dma.c 2008-03-22 17:57:44.000000000 +0100
@@ -854,6 +854,10 @@

if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) {
/* ugh realloc */
+ if (!dma_mapping_error(dma_test))
+ dma_unmap_single(dev->dev->dev,
+ dma_test, b43_txhdr_size(dev),
+ DMA_TO_DEVICE);
kfree(ring->txhdr_cache);
ring->txhdr_cache = kcalloc(nr_slots,
b43_txhdr_size(dev),
@@ -867,8 +871,13 @@
DMA_TO_DEVICE);

if (b43_dma_mapping_error(ring, dma_test,
- b43_txhdr_size(dev)))
+ b43_txhdr_size(dev))) {
+ if (!dma_mapping_error(dma_test))
+ dma_unmap_single(dev->dev->dev,
+ dma_test, b43_txhdr_size(dev),
+ DMA_TO_DEVICE);
goto err_kfree_txhdr_cache;
+ }
}

dma_unmap_single(dev->dev->dev,


2008-03-22 20:59:32

by Michael Büsch

[permalink] [raw]
Subject: Re: [PATCH 2.6.25-rc6] b43/dma.c: fix DMA unmapping in DMA ring error path

On Saturday 22 March 2008 18:32:18 Christian Casteyde wrote:
> This fixes a DMA mapping leak in error path of the b43_setup_dmaring function.
> When DMA mapping fails because of device mask preventing the allocated DMA
> zone from being used, the mapping should be reversed before the second try with GFP_DMA.

This doesn't fix all occurences of the bug.
I'll send a fixed patch later.

> Signed-off-by: Christian Casteyde <[email protected]>
>
> ---
> --- linux-2.6.25.old/drivers/net/wireless/b43/dma.c 2008-03-22 17:28:52.000000000 +0100
> +++ linux-2.6.25/drivers/net/wireless/b43/dma.c 2008-03-22 17:57:44.000000000 +0100
> @@ -854,6 +854,10 @@
>
> if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) {
> /* ugh realloc */
> + if (!dma_mapping_error(dma_test))
> + dma_unmap_single(dev->dev->dev,
> + dma_test, b43_txhdr_size(dev),
> + DMA_TO_DEVICE);
> kfree(ring->txhdr_cache);
> ring->txhdr_cache = kcalloc(nr_slots,
> b43_txhdr_size(dev),
> @@ -867,8 +871,13 @@
> DMA_TO_DEVICE);
>
> if (b43_dma_mapping_error(ring, dma_test,
> - b43_txhdr_size(dev)))
> + b43_txhdr_size(dev))) {
> + if (!dma_mapping_error(dma_test))
> + dma_unmap_single(dev->dev->dev,
> + dma_test, b43_txhdr_size(dev),
> + DMA_TO_DEVICE);
> goto err_kfree_txhdr_cache;
> + }
> }
>
> dma_unmap_single(dev->dev->dev,
>
>



--
Greetings Michael.