diff options
author | françois romieu | 2012-12-01 13:08:50 +0000 |
---|---|---|
committer | David S. Miller | 2012-12-01 20:39:17 -0500 |
commit | 892a925e42adb8192a3c832ad29cbc780fc466f6 (patch) | |
tree | c89458159f626aa6b722d04331b1bb43c258d150 /drivers | |
parent | 64022d0b4e93ea432e95db55a72b8a1c5775f3c0 (diff) |
8139cp: fix coherent mapping leak in error path.
cp_open
[...]
rc = cp_alloc_rings(cp);
if (rc)
return rc;
cp_alloc_rings
[...]
mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES,
&cp->ring_dma, GFP_KERNEL);
- cp_alloc_rings never frees the coherent mapping it allocates
- neither do cp_open when cp_alloc_rings fails
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/realtek/8139cp.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index b01f83a044c4..609125a249d9 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp) static int cp_alloc_rings (struct cp_private *cp) { + struct device *d = &cp->pdev->dev; void *mem; + int rc; - mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, - &cp->ring_dma, GFP_KERNEL); + mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL); if (!mem) return -ENOMEM; cp->rx_ring = mem; cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; - return cp_init_rings(cp); + rc = cp_init_rings(cp); + if (rc < 0) + dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); + + return rc; } static void cp_clean_rings (struct cp_private *cp) |