On 15/06/2024 11:33, Martin-Éric Racine wrote:
On Tue, 29 Aug 2023 13:17:51 +0200 Nicolas Cavallari
<nicolas.cavall...@green-communications.fr> wrote:
Package: dhcpcd-base
Version: 9.4.1-22
Severity: critical
Tags: security
Justification: breaks unrelated software
X-Debbugs-Cc: Debian Security Team <t...@security.debian.org>

When the dhcpcd DHCPv4 client receives a zero-length UDP packet on port
68, the "network proxy" dhcpcd process exits with status 0.  dhcpcd then
stops all network activity:  It does not renew leases and eventually expires
the current lease (unless it has infinite duration) and removes the IP
address, leaving the system without networking.

This bug can be triggered remotely over the internet from any UDP port
and is critical on an internet-facing system that needs DHCP to get
an IP address, such as a gateway, a dedicated server or a VM.

This affects version 9.4.1-22 (stable) and 1:9.4.1-24~deb12u2
(stable proposed update) but not 1:10.0.2-4 (testing/unstable) as
upstream fixed it in 10.0.2:

Upstream Bug report: https://github.com/NetworkConfiguration/dhcpcd/issues/179
Upstream Fix: 
https://github.com/NetworkConfiguration/dhcpcd/commit/8b29c0ddf026c1c5647c3b8c6cfe21699c4056ae

This patch does not apply cleanly to 9.4.1 because the privsep
structure changed in 10.0.2.  It's likely that only the src/privsep.c
hunks about len == 0 and eloop_exit() needs to be backported, the other
changes are just here to avoid compiler warnings about unused
parameters.

Upstream got around releasing a backport of this for branch 9 as
commits 53e2f6de4ba87d0534c89cae674e6c1a48724ef0 and
6e127eac6903524d401b31893167e4529b8ab111 respectively.

You are hereby invited to test and report whether this fixes it for Stable.

I did some quick tests on a VM:

First, with 9.4.1-24~deb12u3 as present in debian stable:

# dhcpcd
dhcpcd-9.4.1 starting
dev: loaded udev
DUID 00:04:56:44:13:1b:34:73:40:28:95:70:ba:03:3b:94:d1:45
enp1s0: IAID 00:a5:5a:70
enp1s0: rebinding lease of 192.168.122.51
enp1s0: leased 192.168.122.51 for 3600 seconds
enp1s0: adding route to 192.168.122.0/24
enp1s0: adding default route via 192.168.122.1
forked to background, child pid 1211
# ps ax | grep dhcpcd
 1211 ?        S      0:00 dhcpcd: [manager] [ip4] [ip6]
 1212 ?        S      0:00 dhcpcd: [privileged proxy]
 1213 ?        S      0:00 dhcpcd: [network proxy]
 1214 ?        S      0:00 dhcpcd: [control proxy]
 1217 ?        S      0:00 dhcpcd: [BPF ARP] enp1s0 192.168.122.51
 1235 pts/0    S+     0:00 grep dhcpcd
# python3 -c 'from socket import *; socket(AF_INET, SOCK_DGRAM).sendto(b"", ("127.0.0.1", 68))'
# ps ax | grep dhcpcd
 1211 ?        S      0:00 dhcpcd: [manager] [ip4] [ip6]
 1212 ?        S      0:00 dhcpcd: [privileged proxy]
 1214 ?        S      0:00 dhcpcd: [control proxy]
 1217 ?        S      0:00 dhcpcd: [BPF ARP] enp1s0 192.168.122.51
 1239 pts/0    S+     0:00 grep dhcpcd

The network proxy (1213) is gone.

Then I apt sourced dhcpcd, applied the two patches, rebuilt debian packages and tested them. The situation is now worse:

# ps ax | grep dhcpcd
 1492 ?        S      0:00 dhcpcd: [manager] [ip4] [ip6]
 1493 ?        S      0:00 dhcpcd: [privileged proxy]
 1494 ?        S      0:00 dhcpcd: [network proxy]
 1495 ?        S      0:00 dhcpcd: [control proxy]
 1498 ?        S      0:00 dhcpcd: [BPF ARP] enp1s0 192.168.122.51
 1516 pts/0    S+     0:00 grep dhcpcd
# python3 -c 'from socket import *; socket(AF_INET, SOCK_DGRAM).sendto(b"", ("127.0.0.1", 68))' [ 1851.428513] dhcpcd[1492]: segfault at 4 ip 004eecd8 sp bf980af0 error 4 in dhcpcd[4cd000+40000] likely on CPU 2 (core 0, socket 2) [ 1851.428523] Code: c4 20 83 c4 0c 5b 5e 5f 5d c3 8d b4 26 00 00 00 00 90 55 89 d5 57 89 c7 56 53 e8 13 0c fe ff 81 c3 63 d0 03 00 83 ec 1c 8b 00 <8b> 52 04 8b 80 78 01 00 00 8b 30 85 f6 0f 84 9c 00 00 00 8d 47 0c
# ps ax | grep dhcpcd
 1493 ?        S      0:00 dhcpcd: [privileged proxy]
 1494 ?        S      0:00 dhcpcd: [network proxy]
 1498 ?        S      0:00 dhcpcd: [BPF ARP] enp1s0 192.168.122.51
 1521 pts/0    S+     0:00 grep dhcpcd

The network proxy survived, but the manager and control proxy didn't. And SIGTERM is not enough to kill the remaining processes.

I then tested this patch from issue #283:

https://github.com/NetworkConfiguration/dhcpcd/commit/727c78f503d456875e2a3cee7609288b537d9d25.patch

And this time, it appears to fix the problem:

# ps ax | grep dhcp
 3248 ?        S      0:00 dhcpcd: [manager] [ip4] [ip6]
 3249 ?        S      0:00 dhcpcd: [privileged proxy]
 3250 ?        S      0:00 dhcpcd: [network proxy]
 3251 ?        S      0:00 dhcpcd: [control proxy]
 3254 ?        S      0:00 dhcpcd: [BPF ARP] enp1s0 192.168.122.51
 3272 pts/1    S+     0:00 grep dhcp
# python3 -c 'from socket import *; socket(AF_INET, SOCK_DGRAM).sendto(b"", ("127.0.0.1", 68))'
# ps ax | grep dhcp
 3248 ?        S      0:00 dhcpcd: [manager] [ip4] [ip6]
 3249 ?        S      0:00 dhcpcd: [privileged proxy]
 3250 ?        S      0:00 dhcpcd: [network proxy]
 3251 ?        S      0:00 dhcpcd: [control proxy]
 3254 ?        S      0:00 dhcpcd: [BPF ARP] enp1s0 192.168.122.51
 3276 pts/1    S+     0:00 grep dhcp

I didn't check if there were any adverse effect or if leases are still renewed. I can't check on the production system before Monday.

Thanks

Reply via email to