From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stephen Hemminger Subject: [PATCH v3 23/30] ipv6: defrag: drop non-last frags smaller than min mtu Date: Thu, 13 Sep 2018 07:58:55 -0700 Message-ID: <20180913145902.17531-24-sthemmin@microsoft.com> References: <20180913145902.17531-1-sthemmin@microsoft.com> Cc: netdev@vger.kernel.org, stable@vger.kernel.org, edumazet@google.com, Florian Westphal , Peter Oskolkov To: davem@davemloft.net, gregkh@linuxfoundation.org Return-path: Received: from mail-pg1-f196.google.com ([209.85.215.196]:34873 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728444AbeIMUJd (ORCPT ); Thu, 13 Sep 2018 16:09:33 -0400 Received: by mail-pg1-f196.google.com with SMTP id 7-v6so2881300pgf.2 for ; Thu, 13 Sep 2018 07:59:40 -0700 (PDT) In-Reply-To: <20180913145902.17531-1-sthemmin@microsoft.com> Sender: netdev-owner@vger.kernel.org List-ID: From: Florian Westphal 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 Cc: Eric Dumazet Signed-off-by: Florian Westphal Signed-off-by: David S. Miller (cherry picked from commit 0ed4229b08c13c84a3c301a08defdc9e7f4467e6) --- 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 a1dc0d6a5949..1d2f07cde01a 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -565,6 +565,10 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) hdr = ipv6_hdr(skb); fhdr = (struct frag_hdr *)skb_transport_header(skb); + if (skb->len - skb_network_offset(skb) < IPV6_MIN_MTU && + fhdr->frag_off & htons(IP6_MF)) + return -EINVAL; + skb_orphan(skb); fq = fq_find(net, fhdr->identification, user, hdr, skb->dev ? skb->dev->ifindex : 0); diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index e1c5fa5e3873..afaad60dc2ac 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -522,6 +522,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; + iif = skb->dev ? skb->dev->ifindex : 0; fq = fq_find(net, fhdr->identification, hdr, iif); if (fq) { -- 2.18.0