aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2013-12-26 08:32:55 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-15 18:28:49 -0500
commitfcd8e312578603626f0d78084d7ec2e444489aa4 (patch)
treeff19bd078056b8892d88019886259c95ec4adc41
parent59d2a52eb56dcdaec3c81c456bf408cbab13bde6 (diff)
virtio_net: don't leak memory or block when too many frags
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/virtio_net.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ec0e9f236ff0..68692af1f488 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -341,7 +341,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
341 if (i >= MAX_SKB_FRAGS) { 341 if (i >= MAX_SKB_FRAGS) {
342 pr_debug("%s: packet too long\n", skb->dev->name); 342 pr_debug("%s: packet too long\n", skb->dev->name);
343 skb->dev->stats.rx_length_errors++; 343 skb->dev->stats.rx_length_errors++;
344 return NULL; 344 goto err_frags;
345 } 345 }
346 page = virtqueue_get_buf(rq->vq, &len); 346 page = virtqueue_get_buf(rq->vq, &len);
347 if (!page) { 347 if (!page) {
@@ -362,6 +362,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
362err_skb: 362err_skb:
363 give_pages(rq, page); 363 give_pages(rq, page);
364 while (--num_buf) { 364 while (--num_buf) {
365err_frags:
365 buf = virtqueue_get_buf(rq->vq, &len); 366 buf = virtqueue_get_buf(rq->vq, &len);
366 if (unlikely(!buf)) { 367 if (unlikely(!buf)) {
367 pr_debug("%s: rx error: %d buffers missing\n", 368 pr_debug("%s: rx error: %d buffers missing\n",