gre: fix a possible skb leak
commit 68c3316311
("v4 GRE: Add TCP segmentation offload for GRE")
added a possible skb leak, because it frees only the head of segment
list, in case a skb_linearize() call fails.
This patch adds a kfree_skb_list() helper to fix the bug.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Pravin B Shelar <pshelar@nicira.com>
Cc: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2b7a5db060
commit
bd8a7036c0
3 changed files with 14 additions and 9 deletions
|
@ -627,6 +627,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
|
|||
}
|
||||
|
||||
extern void kfree_skb(struct sk_buff *skb);
|
||||
extern void kfree_skb_list(struct sk_buff *segs);
|
||||
extern void skb_tx_error(struct sk_buff *skb);
|
||||
extern void consume_skb(struct sk_buff *skb);
|
||||
extern void __kfree_skb(struct sk_buff *skb);
|
||||
|
|
|
@ -483,15 +483,8 @@ EXPORT_SYMBOL(skb_add_rx_frag);
|
|||
|
||||
static void skb_drop_list(struct sk_buff **listp)
|
||||
{
|
||||
struct sk_buff *list = *listp;
|
||||
|
||||
kfree_skb_list(*listp);
|
||||
*listp = NULL;
|
||||
|
||||
do {
|
||||
struct sk_buff *this = list;
|
||||
list = list->next;
|
||||
kfree_skb(this);
|
||||
} while (list);
|
||||
}
|
||||
|
||||
static inline void skb_drop_fraglist(struct sk_buff *skb)
|
||||
|
@ -651,6 +644,17 @@ void kfree_skb(struct sk_buff *skb)
|
|||
}
|
||||
EXPORT_SYMBOL(kfree_skb);
|
||||
|
||||
void kfree_skb_list(struct sk_buff *segs)
|
||||
{
|
||||
while (segs) {
|
||||
struct sk_buff *next = segs->next;
|
||||
|
||||
kfree_skb(segs);
|
||||
segs = next;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(kfree_skb_list);
|
||||
|
||||
/**
|
||||
* skb_tx_error - report an sk_buff xmit error
|
||||
* @skb: buffer that triggered an error
|
||||
|
|
|
@ -178,7 +178,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
|
|||
|
||||
err = __skb_linearize(skb);
|
||||
if (err) {
|
||||
kfree_skb(segs);
|
||||
kfree_skb_list(segs);
|
||||
segs = ERR_PTR(err);
|
||||
goto out;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue