diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2015-10-27 22:40:42 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-11-01 12:01:28 -0500 |
commit | 405c92f7a5417274419192ad134d6dc71aedaaa4 (patch) | |
tree | f8bdf8d76e562a59e793c6959d37ede634cd0a68 /net/ipv6 | |
parent | 682b1a9d3f9686ee43fd66b48605daff00522157 (diff) | |
download | linux-stable-405c92f7a5417274419192ad134d6dc71aedaaa4.tar.gz linux-stable-405c92f7a5417274419192ad134d6dc71aedaaa4.tar.bz2 linux-stable-405c92f7a5417274419192ad134d6dc71aedaaa4.zip |
ipv6: add defensive check for CHECKSUM_PARTIAL skbs in ip_fragment
CHECKSUM_PARTIAL skbs should never arrive in ip_fragment. If we get one
of those warn about them once and handle them gracefully by recalculating
the checksum.
Fixes: commit 32dce968dd987 ("ipv6: Allow for partial checksums on non-ufo packets")
See-also: commit 72e843bb09d45 ("ipv6: ip6_fragment() should check CHECKSUM_PARTIAL")
Cc: Eric Dumazet <edumazet@google.com>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Benjamin Coddington <bcodding@redhat.com>
Cc: Tom Herbert <tom@herbertland.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_output.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 81ac5a970e43..e6a7bd15b9b7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -603,6 +603,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr, &ipv6_hdr(skb)->saddr); + if (skb->ip_summed == CHECKSUM_PARTIAL && + (err = skb_checksum_help(skb))) + goto fail; + hroom = LL_RESERVED_SPACE(rt->dst.dev); if (skb_has_frag_list(skb)) { int first_len = skb_pagelen(skb); @@ -731,10 +735,6 @@ slow_path_clean: } slow_path: - if ((skb->ip_summed == CHECKSUM_PARTIAL) && - skb_checksum_help(skb)) - goto fail; - left = skb->len - hlen; /* Space per frame */ ptr = hlen; /* Where to start from */ |