Patch "udplite: fix partial checksum initialization" has been added to the 4.4-stable tree
From: <gregkh@linuxfoundation.org>
Date: 2018-03-08 18:56:52
This is a note to let you know that I've just added the patch titled
udplite: fix partial checksum initialization
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
udplite-fix-partial-checksum-initialization.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let [off-list ref] know about it.
From foo@baz Thu Mar 8 10:22:29 PST 2018
From: Alexey Kodanev <redacted>
Date: Thu, 15 Feb 2018 20:18:43 +0300
Subject: udplite: fix partial checksum initialization
From: Alexey Kodanev <redacted>
[ 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 <redacted>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/udplite.h | 1 +
net/ipv4/udp.c | 5 +++++
net/ipv6/ip6_checksum.c | 5 +++++
3 files changed, 11 insertions(+)
--- a/include/net/udplite.h
+++ b/include/net/udplite.h@@ -62,6 +62,7 @@ static inline int udplite_checksum_init( UDP_SKB_CB(skb)->cscov = cscov; if (skb->ip_summed == CHECKSUM_COMPLETE) skb->ip_summed = CHECKSUM_NONE; + skb->csum_valid = 0; } return 0; --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c
@@ -1744,6 +1744,11 @@ static inline int udp4_csum_init(struct err = udplite_checksum_init(skb, uh); if (err) return err; + + if (UDP_SKB_CB(skb)->partial_cov) { + skb->csum = inet_compute_pseudo(skb, proto); + return 0; + } } return skb_checksum_init_zero_check(skb, proto, uh->check, --- a/net/ipv6/ip6_checksum.c +++ b/net/ipv6/ip6_checksum.c
@@ -73,6 +73,11 @@ int udp6_csum_init(struct sk_buff *skb, err = udplite_checksum_init(skb, uh); if (err) return err; + + if (UDP_SKB_CB(skb)->partial_cov) { + skb->csum = ip6_compute_pseudo(skb, proto); + return 0; + } } /* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)
Patches currently in stable-queue which might be from alexey.kodanev@oracle.com are queue-4.4/sctp-fix-dst-refcnt-leak-in-sctp_v6_get_dst.patch queue-4.4/udplite-fix-partial-checksum-initialization.patch queue-4.4/sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch