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-next>] [day] [month] [year] [list]
Message-ID: <8260b8a8-fb9f-f9a4-f756-9ef04b67f954@digineo.de>
Date:   Tue, 4 Jun 2019 19:46:05 +0200
From:   Arthur Skowronek <ags@...ineo.de>
To:     Netdev <netdev@...r.kernel.org>
Subject: gue6 bad checksums in udp header

Hello all,

it appears that there is an issue with the content of the checksum field 
in udp packets which are transmitted through a gue encapsulated ipip 
tunnel over ipv6.

I spent the past few days with experimenting around with the gue 
encapsulation capabilities for ipip tunnels in the linux kernel. The 
first system is running the version 4.14.121 from openwrt on an ubiquiti 
edgerouter x and the second system is my workstation PC which is running 
the linux kernel 4.19.47 and arch linux.

The gue feature on the edgerouter x seems to be broken though.  All 
packets originating from this system have a bad UDP checksum.  Packets 
coming from my workstation are fine though. I assume that the problem 
lies somewhere in the kernel because all operations involving the ip 
tunnel are handled in kernel and it doesn't seem like userspace is 
involved at all. I don't think it's an exact issue with the embedded 
device itself since other UDP packets which are sent over ipv6 are fine. 
It seems to be an isolated issue with the gue implementation of the 
kernel in combination with this device.

This is the script I use to set up the tunneling:

	# To be executed on the router
	export systemA='2a06:redacted::163'
	export systemB='2a06:redacted::21'

	ip fou add port 9191 gue -6
	ip link add name fou type ip6tnl \
	    remote "$systemB" local "$systemA" \
	    encap gue encap-dport 9191 encap-sport 9191 mode any
	ip link set up dev fou
	ip addr add 'fe80::1' dev fou

	# To be executed on the workstation
	export systemA='2a06:redacted::163'
	export systemB='2a06:redacted::21'

	ip fou add port 9191 gue -6
	ip link add name fou type ip6tnl \
	    remote "$systemA" local "$systemB" \
	    encap gue encap-dport 9191 encap-sport 9191 mode any
	ip link set up dev fou
	ip addr add 'fe80::2' dev fou

This works and the interfaces are allocated properly. When I try to ping 
the workstation from the ERX device now it seems that the packets sent 
by the router have the wrong UDP checksum though. This is taken from 
wireshark:

	Internet Protocol Version 6, Src: 2a06:redacted::163, Dst: 
2a06:redacted::21
	    0110 .... = Version: 6
	    .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 
(DSCP: CS0, ECN: Not-ECT)
	    .... .... .... 1101 0000 1111 0000 0001 = Flow Label: 0xd0f01
	    Payload Length: 124
	    Next Header: Destination Options for IPv6 (60)
	    Hop Limit: 64
	    Source: 2a06:redacted::163
	    Destination: 2a06:redacted::21
	    Destination Options for IPv6
		Next Header: UDP (17)
		Length: 0
		[Length: 8 bytes]
		Tunnel Encapsulation Limit
		PadN
	User Datagram Protocol, Src Port: 9191, Dst Port: 9191
	    Source Port: 9191
	    Destination Port: 9191
	    Length: 116
	    Checksum: 0x2272 incorrect, should be 0xec0d (maybe caused by "UDP 
checksum offload"?)
	    [Checksum Status: Bad]
	    [Stream index: 69]
	    [Timestamps]
	Data (108 bytes)
	    Data: 00290000600d0f0100403a40fe8000000000000000000000…
	    [Length: 108]

Unfortunatelly I'm not particularly well versed in the internals of the 
Linux networking code so it's a little bit difficult for me to debug the 
problem in greater detail.  From what I can tell it seems like the the 
checksum is only computed over the pseudo IP header, missing out the UDP 
Header and the GUE header.  As far as I understand the documents 
describing UDP in ip6 it seems that the checksum needs to be generated 
over the entire payload for UDP in ip6 though.

I don't know how to solve this problem in a way that works nicely with 
the checksum offloading capabilities in the kernel though.  I have no 
experience in developing directly in the Linux kernel and this subsystem 
looks really intimidating to me.  Any help in solving this problem would 
be greatly appreciated.  Thank you very much.


Greetings,
Arthur Skowronek

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ