Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd8a7036 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

gre: fix a possible skb leak



commit 68c33163 ("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: default avatarEric Dumazet <edumazet@google.com>
Cc: Pravin B Shelar <pshelar@nicira.com>
Cc: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2b7a5db0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+12 −8
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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;
				}