diff options
author | Alexey Kodanev <alexey.kodanev@oracle.com> | 2018-02-15 20:18:43 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-03-11 16:12:19 +0100 |
commit | 6b709dae4841b60188600fef468bbf71aca0584b (patch) | |
tree | fa0ccce96cbe5eea6bb8d535c262fe67028aafd4 /include/net | |
parent | 794953c9fb6bdcbbd86251cf8505ede9b357a135 (diff) | |
download | linux-stable-6b709dae4841b60188600fef468bbf71aca0584b.tar.gz linux-stable-6b709dae4841b60188600fef468bbf71aca0584b.tar.bz2 linux-stable-6b709dae4841b60188600fef468bbf71aca0584b.zip |
udplite: fix partial checksum initialization
[ Upstream commit 15f35d49c93f4fa9875235e7bf3e3783d2dd7a1b ]
Since UDP-Lite is always using checksum, the following path is
triggered when calculating pseudo header for it:
udp4_csum_init() or udp6_csum_init()
skb_checksum_init_zero_check()
__skb_checksum_validate_complete()
The problem can appear if skb->len is less than CHECKSUM_BREAK. In
this particular case __skb_checksum_validate_complete() also invokes
__skb_checksum_complete(skb). If UDP-Lite is using partial checksum
that covers only part of a packet, the function will return bad
checksum and the packet will be dropped.
It can be fixed if we skip skb_checksum_init_zero_check() and only
set the required pseudo header checksum for UDP-Lite with partial
checksum before udp4_csum_init()/udp6_csum_init() functions return.
Fixes: ed70fcfcee95 ("net: Call skb_checksum_init in IPv4")
Fixes: e4f45b7f40bd ("net: Call skb_checksum_init in IPv6")
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/udplite.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/net/udplite.h b/include/net/udplite.h index 2caadabcd07b..3c8985489992 100644 --- a/include/net/udplite.h +++ b/include/net/udplite.h @@ -61,6 +61,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) UDP_SKB_CB(skb)->cscov = cscov; if (skb->ip_summed == CHECKSUM_COMPLETE) skb->ip_summed = CHECKSUM_NONE; + skb->csum_valid = 0; } return 0; |