Skip to content

Commit 6f5cade

Browse files
joestringerdavem330
authored andcommitted
openvswitch: Fix skb leak using IPv6 defrag
nf_ct_frag6_gather() makes a clone of each skb passed to it, and if the reassembly is successful, expects the caller to free all of the original skbs using nf_ct_frag6_consume_orig(). This call was previously missing, meaning that the original fragments were never freed (with the exception of the last fragment to arrive). Fix this by ensuring that all original fragments except for the last fragment are freed via nf_ct_frag6_consume_orig(). The last fragment will be morphed into the head, so it must not be freed yet. Furthermore, retain the ->next pointer for the head after skb_morph(). Fixes: 7f8a436 ("openvswitch: Add conntrack action") Reported-by: Florian Westphal <[email protected]> Signed-off-by: Joe Stringer <[email protected]> Acked-by: Pravin B Shelar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 190b8ff commit 6f5cade

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

net/openvswitch/conntrack.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,15 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
326326
return -EINVAL;
327327
}
328328

329+
/* Don't free 'skb' even though it is one of the original
330+
* fragments, as we're going to morph it into the head.
331+
*/
332+
skb_get(skb);
333+
nf_ct_frag6_consume_orig(reasm);
334+
329335
key->ip.proto = ipv6_hdr(reasm)->nexthdr;
330336
skb_morph(skb, reasm);
337+
skb->next = reasm->next;
331338
consume_skb(reasm);
332339
ovs_cb.mru = IP6CB(skb)->frag_max_size;
333340
#endif

0 commit comments

Comments
 (0)