Skip to content

Commit

Permalink
openvswitch: Fix skb leak using IPv6 defrag
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
joestringer authored and davem330 committed Oct 28, 2015
1 parent 190b8ff commit 6f5cade
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions net/openvswitch/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,15 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
return -EINVAL;
}

/* Don't free 'skb' even though it is one of the original
* fragments, as we're going to morph it into the head.
*/
skb_get(skb);
nf_ct_frag6_consume_orig(reasm);

key->ip.proto = ipv6_hdr(reasm)->nexthdr;
skb_morph(skb, reasm);
skb->next = reasm->next;
consume_skb(reasm);
ovs_cb.mru = IP6CB(skb)->frag_max_size;
#endif
Expand Down

0 comments on commit 6f5cade

Please sign in to comment.