From: Florian Westphal <f...@strlen.de>

[ Upstream commit 0ed4229b08c13c84a3c301a08defdc9e7f4467e6 ]

don't bother with pathological cases, they only waste cycles.
IPv6 requires a minimum MTU of 1280 so we should never see fragments
smaller than this (except last frag).

v3: don't use awkward "-offset + len"
v2: drop IPv4 part, which added same check w. IPV4_MIN_MTU (68).
    There were concerns that there could be even smaller frags
    generated by intermediate nodes, e.g. on radio networks.

Cc: Peter Oskolkov <p...@google.com>
Cc: Eric Dumazet <eduma...@google.com>
Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Mao Wenan <maowe...@huawei.com>
---
 net/ipv6/netfilter/nf_conntrack_reasm.c | 4 ++++
 net/ipv6/reassembly.c                   | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c 
b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 9cd8863..88bfae1 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -602,6 +602,10 @@ struct sk_buff *nf_ct_frag6_gather(struct net *net, struct 
sk_buff *skb, u32 use
        hdr = ipv6_hdr(clone);
        fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
+       if (skb->len - skb_network_offset(skb) < IPV6_MIN_MTU &&
+           fhdr->frag_off & htons(IP6_MF))
+               goto ret_orig;
+
        skb_orphan(skb);
        fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
                     skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index adc7512..44c7f4c 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -549,6 +549,10 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                return 1;
        }
 
+       if (skb->len - skb_network_offset(skb) < IPV6_MIN_MTU &&
+           fhdr->frag_off & htons(IP6_MF))
+               goto fail_hdr;
+
        fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
                     skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
        if (fq) {
-- 
1.8.3.1

Reply via email to