lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed,  5 May 2021 17:35:03 +0200
From:   Paolo Abeni <pabeni@...hat.com>
To:     netdev@...r.kernel.org
Cc:     "David S. Miller" <davem@...emloft.net>,
        Jakub Kicinski <kuba@...nel.org>,
        Steffen Klassert <steffen.klassert@...unet.com>,
        Willem de Bruijn <willemb@...gle.com>,
        Miaohe Lin <linmiaohe@...wei.com>
Subject: [PATCH net 3/4] udp: fix outer header csum for SKB_GSO_FRAGLIST over UDP tunnel

In the following scenario:

    GRO -> SKB_GSO_FRAGLIST aggregation -> forward ->
      xmit over UDP tunnel

SKB_GSO_FRAGLIST packet traverse an UDP tunnel in the xmit path.
The tunnel code sets up the outer header csum via udp_set_csum()
and the latter assumes that each GSO packet is CHECKSUM_PARTIAL.

Since the introduction of SKB_GSO_FRAGLIST and veth GRO, the above
assumption is not true anymore as SKB_GSO_FRAGLIST are
CHECKSUM_UNNECESSARY, and the csum for the outer header will be
left uninitialized.

All the above will cause wrong outer UDP header checksum when the
mentioned packet will be xmitted on some real NIC.

This change addresses the issue explicitly checking for both gso and
CHECKSUM_PARTIAL in udp_set_csum(), so that the mentioned packet will
be processed correctly.

Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
Signed-off-by: Paolo Abeni <pabeni@...hat.com>
---
 net/ipv4/udp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 15f5504adf5b..055fceb18bea 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -857,7 +857,7 @@ void udp_set_csum(bool nocheck, struct sk_buff *skb,
 
 	if (nocheck) {
 		uh->check = 0;
-	} else if (skb_is_gso(skb)) {
+	} else if (skb_is_gso(skb) && skb->ip_summed == CHECKSUM_PARTIAL) {
 		uh->check = ~udp_v4_check(len, saddr, daddr, 0);
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		uh->check = 0;
-- 
2.26.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ