diff options
| author | 陈谋顺 <[email protected]> | 2026-10-09 11:16:57 +0800 |
|---|---|---|
| committer | Rbb666 <[email protected]> | 2026-10-10 17:20:57 +0800 |
| commit | 887ca7175cfef7f11f8566020d23335e9a73f271 (patch) | |
| tree | 0fda17a87a261925543091a16c9aa6709438ece0 | |
| parent | cd92c3d06c880d097059ee3e0bf17cd54abb4603 (diff) | |
[components][lwip] dhcpd: check buffer bounds when parsing options
The option loop advanced by the option length without checking the
number of bytes actually received by recvfrom(), so a malformed or
truncated DHCP packet could make the server read past the end of the
receive buffer.
Check that the option type, length and payload stay inside the received
data before reading them, and stop parsing when a requested IP option
is shorter than 4 bytes or a message type option is shorter than 1 byte.
Fixes #11323
| -rw-r--r-- | components/net/lwip-dhcpd/dhcp_server.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/components/net/lwip-dhcpd/dhcp_server.c b/components/net/lwip-dhcpd/dhcp_server.c index 0cc08b5a6e..9df685ebe5 100644 --- a/components/net/lwip-dhcpd/dhcp_server.c +++ b/components/net/lwip-dhcpd/dhcp_server.c @@ -331,6 +331,7 @@ static void dhcpd_thread_entry(void *parameter) /* handler. */ { uint8_t *dhcp_opt; + uint8_t *dhcp_opt_end; uint8_t option; uint8_t length; @@ -343,14 +344,31 @@ static void dhcpd_thread_entry(void *parameter) client_ip_3 = get_ip(&mac_addr); dhcp_opt = (uint8_t *)msg + DHCP_OPTIONS_OFS; + dhcp_opt_end = (uint8_t *)msg + bytes_read; while (finished == 0) { + /* need at least option + length */ + if (dhcp_opt + 2 > dhcp_opt_end) + { + break; + } + option = *dhcp_opt; length = *(dhcp_opt + 1); + /* option data must stay within the received packet */ + if (option != DHCP_OPTION_END && dhcp_opt + 2 + length > dhcp_opt_end) + { + break; + } + switch (option) { case DHCP_OPTION_REQUESTED_IP: + if (length < 4) + { + break; + } request_ip = *(dhcp_opt + 2) << 24 | *(dhcp_opt + 3) << 16 | *(dhcp_opt + 4) << 8 | *(dhcp_opt + 5); break; @@ -360,6 +378,10 @@ static void dhcpd_thread_entry(void *parameter) break; case DHCP_OPTION_MESSAGE_TYPE: + if (length < 1) + { + break; + } message_type = *(dhcp_opt + 2); break; |
