Package: tftpd-hpa
Version: 5.2+20240610-3
Severity: important
X-Debbugs-CC: ha...@debian.org
Tags: patch

Dear tftpd-hpa maintainers,

When tftpd is deployed on servers with multiple addresses, if the client
is reaching the server via an address which is not preferred as a source
address when the server is sending the replying packets, the communication
will fail, since the client is receiving packets from unexpected source
address and rejecting them.

This can be reproduced using the following steps:

# create a netns and create a pair of veths
ip netns add ns1
ip link add veth1 type veth peer name veth2 
ip link set veth1 up
ip link set veth2 netns ns1 name eth0 up

# assign two IPs for veth1
ip addr add 10.0.0.1/24 dev veth1
ip addr add 10.0.0.2/24 dev veth1

# assign one IP for eth0 in ns1
ip netns exec ns1 ip link set lo up
ip netns exec ns1 ip addr add 10.0.0.3/24 dev eth0

# put some file in /srv/tftp, the file should be larger than 1 transfer block
seq 1 1024 > /srv/tftp/foo

# start the server
in.tftpd --listen --foreground --address 0.0.0.0 --secure /srv/tftp

# try to download the data within ns1
ip netns exec ns1 tftp 10.0.0.1
tftp> get foo
# it works normally

# try to download the data within ns1, but use the secondary IP of the server 
interface
ip netns exec ns1 tftp 10.0.0.2
tftp> get foo
# it will get stuck

By capturing the traffic, we can see tftpd is trying to send response
packets to 10.0.0.3 from 10.0.0.1 instead of 10.0.0.2 and is also unable to
receive the ACK packets from the client.

tcpdump: listening on veth1, link-type EN10MB (Ethernet), snapshot length 
262144 bytes
13:32:53.760731 IP (tos 0x0, ttl 64, id 18689, offset 0, flags [DF], proto UDP 
(17), length 43)
    10.0.0.3.49134 > 10.0.0.2.69: [bad udp cksum 0x142d -> 0x9683!] TFTP, 
length 15, RRQ "foo" netascii
13:32:53.761375 IP (tos 0x0, ttl 64, id 62903, offset 0, flags [none], proto 
UDP (17), length 544)
    10.0.0.1.47636 > 10.0.0.3.49134: [bad udp cksum 0x1621 -> 0x86b8!] UDP, 
length 516
13:32:53.761454 IP (tos 0x0, ttl 64, id 18690, offset 0, flags [DF], proto UDP 
(17), length 32)
    10.0.0.3.49134 > 10.0.0.2.47636: [bad udp cksum 0x1422 -> 0x71c9!] UDP, 
length 4
13:32:53.761464 IP (tos 0xc0, ttl 64, id 49801, offset 0, flags [none], proto 
ICMP (1), length 60)
    10.0.0.2 > 10.0.0.3: ICMP 10.0.0.2 udp port 47636 unreachable, length 40
IP (tos 0x0, ttl 64, id 18690, offset 0, flags [DF], proto UDP (17), length 32)
    10.0.0.3.49134 > 10.0.0.2.47636: [bad udp cksum 0x1422 -> 0x71c9!] UDP, 
length 4
13:32:54.767567 IP (tos 0x0, ttl 64, id 62904, offset 0, flags [none], proto 
UDP (17), length 544)
    10.0.0.1.47636 > 10.0.0.3.49134: [bad udp cksum 0x1621 -> 0x86b8!] UDP, 
length 516
13:32:54.767706 IP (tos 0x0, ttl 64, id 18845, offset 0, flags [DF], proto UDP 
(17), length 32)
    10.0.0.3.49134 > 10.0.0.2.47636: [bad udp cksum 0x1422 -> 0x71c9!] UDP, 
length 4
13:32:54.767720 IP (tos 0xc0, ttl 64, id 49804, offset 0, flags [none], proto 
ICMP (1), length 60)
    10.0.0.2 > 10.0.0.3: ICMP 10.0.0.2 udp port 47636 unreachable, length 40
IP (tos 0x0, ttl 64, id 18845, offset 0, flags [DF], proto UDP (17), length 32)
    10.0.0.3.49134 > 10.0.0.2.47636: [bad udp cksum 0x1422 -> 0x71c9!] UDP, 
length 4

The root cause of this problem is during the upstream refactoring the autoconf
system, some feature test macros are left out, so the function  myrecvfrom()
cannot properly obtain the local address used to receive the packets from the
client.

I have posted patch series to fix this problem to the upstream [1]. The second
patch in the series can also fix another problem inside myrecvfrom() that
prevents the above setup from working, which I'd like to have it into stable-pu.

[1]: https://www.syslinux.org/archives/2025-July/026938.html

Cheers,

Miao Wang

Reply via email to