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]
Date: Wed, 08 Nov 2023 11:58:57 +0100
From: Jakub Sitnicki <jakub@...udflare.com>
To: Willem de Bruijn <willemb@...gle.com>
Cc: netdev@...r.kernel.org, kernel-team@...udflare.com
Subject: EIO on send with UDP_SEGMENT

Hi Willem et al,

We have hit the EIO error path in udp_send_skb introduced in commit bec1f6f69736
("udp: generate gso with UDP_SEGMENT") [0]:

	if (skb->ip_summed != CHECKSUM_PARTIAL || ...) {
		kfree_skb(skb);
		return -EIO;
	}

... when attempting to send a GSO packet, using UDP_SEGMENT option, from
a TUN device which didn't have any offloads enabled (the default case).

A trivial reproducer for that would be:

  ip tuntap add dev tun0 mode tun
  ip addr add dev tun0 192.0.2.1/24
  ip link set dev tun0 up
  
  strace -e %net python -c '
  from socket import *
  s = socket(AF_INET, SOCK_DGRAM)
  s.setsockopt(SOL_UDP, 103, 1200)
  s.sendto(b"x" * 3000, ("192.0.2.2", 9))
  '

which yields:

  socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 3
  setsockopt(3, SOL_UDP, UDP_SEGMENT, [1200], 4) = 0
  sendto(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 3000, 0, {sa_family=AF_INET, sin_port=htons(9), sin_addr=inet_addr("192.0.2.2")}, 16) = -1 EIO (Input/output error)

This has been a surprise and caused us some pain. I think it comes down
to that anyone using UDP_SEGMENT has to implement a segmentation
fallback in user-space. Just to be on the safe side.  We can't really
assume that any TUN/TAP interface, which happens to be our egress
device, has at least checksum offload enabled and implemented.

Which is not ideal.
So it made us wonder if anything can be done about it?

As it turns out, skb_segment() in GSO path implements a software
fallback not only for segmentation but also for checksumming [1].

What is more, when we removed the skb->ip_summed == CHECKSUM_PARTIAL
restriction in udp_send, as an experiment, we were able to observe fully
checksummed segments in packet capture.

Which brings me to my question -

Do you think the restriction in udp_send_skb can be lifted or tweaked?

Thanks,
Jakub

[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bec1f6f697362c5bc635dacd7ac8499d0a10a4e7
[1] https://elixir.bootlin.com/linux/v6.6/source/net/core/skbuff.c#L4626

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ