Commit effb6d24 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Greg Kroah-Hartman

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: default avatarMichael Dalton <mwdalton@google.com>
Acked-by: default avatarMichael Dalton <mwdalton@google.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent aa016e2d
...@@ -344,7 +344,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, ...@@ -344,7 +344,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
if (i >= MAX_SKB_FRAGS) { if (i >= MAX_SKB_FRAGS) {
pr_debug("%s: packet too long\n", skb->dev->name); pr_debug("%s: packet too long\n", skb->dev->name);
skb->dev->stats.rx_length_errors++; skb->dev->stats.rx_length_errors++;
return NULL; goto err_frags;
} }
page = virtqueue_get_buf(rq->vq, &len); page = virtqueue_get_buf(rq->vq, &len);
if (!page) { if (!page) {
...@@ -365,6 +365,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, ...@@ -365,6 +365,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
err_skb: err_skb:
give_pages(rq, page); give_pages(rq, page);
while (--num_buf) { while (--num_buf) {
err_frags:
buf = virtqueue_get_buf(rq->vq, &len); buf = virtqueue_get_buf(rq->vq, &len);
if (unlikely(!buf)) { if (unlikely(!buf)) {
pr_debug("%s: rx error: %d buffers missing\n", pr_debug("%s: rx error: %d buffers missing\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment