8139cp: fix coherent mapping leak in error path.
authorfran├žois romieu <romieu@fr.zoreil.com>
Sat, 1 Dec 2012 13:08:50 +0000 (13:08 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 2 Dec 2012 01:39:17 +0000 (20:39 -0500)
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>
drivers/net/ethernet/realtek/8139cp.c

index b01f83a044c4d77f70141c81fee3815cd050f258..609125a249d9484835f77fd445e6a8ba32e299db 100644 (file)
@@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp)
 
 static int cp_alloc_rings (struct cp_private *cp)
 {
 
 static int cp_alloc_rings (struct cp_private *cp)
 {
+       struct device *d = &cp->pdev->dev;
        void *mem;
        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];
 
        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)
 }
 
 static void cp_clean_rings (struct cp_private *cp)