mirror of
https://github.com/systemd/systemd.git
synced 2026-08-04 15:10:33 +00:00
dhcp-client: clear overloaded sname/file fields after parsing
When SD_DHCP_OPTION_OVERLOAD indicates that the sname and/or file header fields are overloaded with extra DHCP options, dhcp_message_parse() merges those options into message->options but leaves the raw bytes untouched in the header. As a result, dhcp_message_build() emits the header (including the overloaded bytes) verbatim, and the next parse re-parses those bytes, appending duplicate entries to the options map (each tag's iov list grows). Subsequent builds then differ from the first, breaking the parse/build roundtrip. This was caught by fuzz-dhcp-client, which asserts that two consecutive build calls produce identical output. Zero out the overloaded fields after parsing them, since their content has already been merged into the options map. This makes the roundtrip idempotent and avoids re-emitting stale overloaded data in the rebuilt header. The JSON build/parse path was already correct (it omits sname/file from the JSON when the overload bit is set), so only the binary path needed fixing. Fixes https://github.com/systemd/systemd/issues/42139 Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
committed by
Yu Watanabe
parent
aa0f03eb03
commit
1d73c5f04f
@@ -1409,12 +1409,19 @@ int dhcp_message_parse(
|
||||
r = tlv_parse(&message->options, &IOVEC_MAKE(message->header.file, sizeof(message->header.file)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* The content of the overloaded field has been merged into options. Clear it so that the
|
||||
* field is not re-parsed (which would duplicate the options) and not re-emitted verbatim
|
||||
* by dhcp_message_build(), ensuring parse/build is idempotent. */
|
||||
memzero(message->header.file, sizeof(message->header.file));
|
||||
}
|
||||
|
||||
if (FLAGS_SET(overload, DHCP_OVERLOAD_SNAME)) {
|
||||
r = tlv_parse(&message->options, &IOVEC_MAKE(message->header.sname, sizeof(message->header.sname)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
memzero(message->header.sname, sizeof(message->header.sname));
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(message);
|
||||
|
||||
BIN
test/fuzz/fuzz-dhcp-client/overload-file-roundtrip
Normal file
BIN
test/fuzz/fuzz-dhcp-client/overload-file-roundtrip
Normal file
Binary file not shown.
Reference in New Issue
Block a user