]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp-client: reject messages larger than the maximum UDP payload
authorLuca Boccassi <luca.boccassi@gmail.com>
Mon, 18 May 2026 11:05:10 +0000 (12:05 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 18 May 2026 16:43:25 +0000 (01:43 +0900)
dhcp_message_verify_header() only enforced a lower bound on the input
length, so dhcp_message_parse() happily accepted arbitrarily large
buffers. Such inputs could never have been received via UDP and would
later fail in dhcp_message_build() with -E2BIG once the parsed options'
combined size exceeds UDP_PAYLOAD_MAX_SIZE, which the fuzzer surfaced as
an assertion failure.

Reject inputs above UDP_PAYLOAD_MAX_SIZE up front, so the parse stage
mirrors what the wire format can actually carry.

Follow-up for 8c18bb6547c2138f2f17b921ec06f2c1f7cd17cd

Fixes https://github.com/systemd/systemd/issues/42147

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
src/libsystemd-network/dhcp-message.c
test/fuzz/fuzz-dhcp-client/oversized-message [new file with mode: 0644]

index bf85dd4233185b18466dfb36f9f34e4801672cbe..14671a07508259d6d02d3b17edcdfd3bc7051bb8 100644 (file)
@@ -1342,6 +1342,11 @@ static int dhcp_message_verify_header(
         if (iov->iov_len < sizeof(DHCPMessageHeader))
                 return -EBADMSG;
 
+        /* DHCP travels over UDP, so anything larger than the maximum UDP payload cannot be a valid
+         * message and would also be impossible to rebuild as a UDP packet. */
+        if (iov->iov_len > UDP_PAYLOAD_MAX_SIZE)
+                return -EBADMSG;
+
         const DHCPMessageHeader *header = iov->iov_base;
 
         if (!IN_SET(header->op, BOOTREQUEST, BOOTREPLY))
diff --git a/test/fuzz/fuzz-dhcp-client/oversized-message b/test/fuzz/fuzz-dhcp-client/oversized-message
new file mode 100644 (file)
index 0000000..a1b3f69
Binary files /dev/null and b/test/fuzz/fuzz-dhcp-client/oversized-message differ