| From foo@baz Mon Sep 17 13:33:56 CEST 2018 |
| From: Stephen Hemminger <stephen@networkplumber.org> |
| Date: Thu, 13 Sep 2018 07:58:55 -0700 |
| Subject: ipv6: defrag: drop non-last frags smaller than min mtu |
| To: davem@davemloft.net, gregkh@linuxfoundation.org |
| Cc: netdev@vger.kernel.org, stable@vger.kernel.org, edumazet@google.com, Florian Westphal <fw@strlen.de>, Peter Oskolkov <posk@google.com> |
| Message-ID: <20180913145902.17531-24-sthemmin@microsoft.com> |
| |
| From: Florian Westphal <fw@strlen.de> |
| |
| 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 <posk@google.com> |
| Cc: Eric Dumazet <edumazet@google.com> |
| Signed-off-by: Florian Westphal <fw@strlen.de> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| (cherry picked from commit 0ed4229b08c13c84a3c301a08defdc9e7f4467e6) |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ipv6/netfilter/nf_conntrack_reasm.c | 4 ++++ |
| net/ipv6/reassembly.c | 4 ++++ |
| 2 files changed, 8 insertions(+) |
| |
| --- 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, |
| 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); |
| --- a/net/ipv6/reassembly.c |
| +++ b/net/ipv6/reassembly.c |
| @@ -522,6 +522,10 @@ static int ipv6_frag_rcv(struct sk_buff |
| 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) { |