macvlan: Fix leak and NULL dereference on error path
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 22 Apr 2014 09:15:34 +0000 (17:15 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 Apr 2014 18:55:30 +0000 (14:55 -0400)
The recent patch that moved broadcasts to process context added
a couple of bugs on the error path where we may dereference NULL
or leak an skb.  This patch fixes them.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/macvlan.c

index 8b8220fcdd3d2e7448f1834d4462924d27b3d2c5..cfb27c86541798cc1819ce467f09522628abbd1f 100644 (file)
@@ -239,25 +239,28 @@ static void macvlan_process_broadcast(struct work_struct *w)
 static void macvlan_broadcast_enqueue(struct macvlan_port *port,
                                      struct sk_buff *skb)
 {
+       struct sk_buff *nskb;
        int err = -ENOMEM;
 
-       skb = skb_clone(skb, GFP_ATOMIC);
-       if (!skb)
+       nskb = skb_clone(skb, GFP_ATOMIC);
+       if (!nskb)
                goto err;
 
        spin_lock(&port->bc_queue.lock);
        if (skb_queue_len(&port->bc_queue) < skb->dev->tx_queue_len) {
-               __skb_queue_tail(&port->bc_queue, skb);
+               __skb_queue_tail(&port->bc_queue, nskb);
                err = 0;
        }
        spin_unlock(&port->bc_queue.lock);
 
        if (err)
-               goto err;
+               goto free_nskb;
 
        schedule_work(&port->bc_work);
        return;
 
+free_nskb:
+       kfree_skb(nskb);
 err:
        atomic_long_inc(&skb->dev->rx_dropped);
 }