xen-netback: unref frags when handling a from-guest skb with a frag list
Every time a VIF is destroyed up to 256 pages may be leaked if packets with more than MAX_SKB_FRAGS frags were transmitted from the guest. Even worse, if another user of ballooned pages allocated one of these ballooned pages it would not handle the unexpectedly >1 page count (e.g., gntdev would deadlock when unmapping a grant because the page count would never reach 1). When handling a from-guest skb with a frag list, unref the frags before releasing them so they are freed correctly when the VIF is destroyed. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
d63951d744
Коммит
49d9991a18
|
@ -1349,7 +1349,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
|
||||||
{
|
{
|
||||||
unsigned int offset = skb_headlen(skb);
|
unsigned int offset = skb_headlen(skb);
|
||||||
skb_frag_t frags[MAX_SKB_FRAGS];
|
skb_frag_t frags[MAX_SKB_FRAGS];
|
||||||
int i;
|
int i, f;
|
||||||
struct ubuf_info *uarg;
|
struct ubuf_info *uarg;
|
||||||
struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
|
struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
|
||||||
|
|
||||||
|
@ -1389,6 +1389,11 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
|
||||||
frags[i].page_offset = 0;
|
frags[i].page_offset = 0;
|
||||||
skb_frag_size_set(&frags[i], len);
|
skb_frag_size_set(&frags[i], len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release all the original (foreign) frags. */
|
||||||
|
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
|
||||||
|
skb_frag_unref(skb, f);
|
||||||
|
|
||||||
/* swap out with old one */
|
/* swap out with old one */
|
||||||
memcpy(skb_shinfo(skb)->frags,
|
memcpy(skb_shinfo(skb)->frags,
|
||||||
frags,
|
frags,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче