virtio_net: don't leak memory or block when too many frags
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 26 Dec 2013 13:32:55 +0000 (15:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jan 2014 23:31:37 +0000 (15:31 -0800)
We leak an skb when there are too many frags,
we also stop processing the packet in the middle,
the result is almost sure to be loss of networking.

Reported-by: Michael Dalton <mwdalton@google.com>
Acked-by: Michael Dalton <mwdalton@google.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/virtio_net.c

index 21f2b4a0f193537ef0d8759d0afc3c09532a0537..a2d19229f49b786e92f6d39d0d1bdb1ca54c66f2 100644 (file)
@@ -344,7 +344,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                if (i >= MAX_SKB_FRAGS) {
                        pr_debug("%s: packet too long\n", skb->dev->name);
                        skb->dev->stats.rx_length_errors++;
-                       return NULL;
+                       goto err_frags;
                }
                page = virtqueue_get_buf(rq->vq, &len);
                if (!page) {
@@ -365,6 +365,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 err_skb:
        give_pages(rq, page);
        while (--num_buf) {
+err_frags:
                buf = virtqueue_get_buf(rq->vq, &len);
                if (unlikely(!buf)) {
                        pr_debug("%s: rx error: %d buffers missing\n",