fix(lwip): Fix DHCP servver OOB read issue

This commit is contained in:
David Cermak
2026-04-09 15:14:23 +02:00
committed by Euripedes Rocha
parent a681415af6
commit 2da2db43fd

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -49,6 +49,7 @@
#define DHCPNAK 6 #define DHCPNAK 6
#define DHCPRELEASE 7 #define DHCPRELEASE 7
#define DHCP_OPTION_PAD 0
#define DHCP_OPTION_SUBNET_MASK 1 #define DHCP_OPTION_SUBNET_MASK 1
#define DHCP_OPTION_ROUTER 3 #define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6 #define DHCP_OPTION_DNS_SERVER 6
@@ -879,7 +880,6 @@ static void send_ack(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
static u8_t parse_options(dhcps_t *dhcps, u8_t *optptr, s16_t len) static u8_t parse_options(dhcps_t *dhcps, u8_t *optptr, s16_t len)
{ {
ip4_addr_t client; ip4_addr_t client;
bool is_dhcp_parse_end = false;
struct dhcps_state s; struct dhcps_state s;
client.addr = *((uint32_t *) &dhcps->client_address); client.addr = *((uint32_t *) &dhcps->client_address);
@@ -894,38 +894,52 @@ static u8_t parse_options(dhcps_t *dhcps, u8_t *optptr, s16_t len)
DHCPS_LOG("dhcps: (s16_t)*optptr = %d\n", (s16_t)*optptr); DHCPS_LOG("dhcps: (s16_t)*optptr = %d\n", (s16_t)*optptr);
#endif #endif
if (*optptr == DHCP_OPTION_PAD) {
optptr++;
continue;
}
if (*optptr == DHCP_OPTION_END) {
break;
}
if (optptr + 1 >= end) {
break;
}
u8_t opt_len = optptr[1];
if (optptr + 2 + opt_len > end) {
break;
}
switch ((s16_t) *optptr) { switch ((s16_t) *optptr) {
case DHCP_OPTION_MSG_TYPE: //53 case DHCP_OPTION_MSG_TYPE: //53
type = *(optptr + 2); if (opt_len >= 1) {
type = optptr[2];
}
break; break;
case DHCP_OPTION_REQ_IPADDR://50 case DHCP_OPTION_REQ_IPADDR://50
if (memcmp((char *) &client.addr, (char *) optptr + 2, 4) == 0) { if (opt_len >= 4) {
if (memcmp((char *) &client.addr, (char *) optptr + 2, 4) == 0) {
#if DHCPS_DEBUG #if DHCPS_DEBUG
DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n");
#endif #endif
s.state = DHCPS_STATE_ACK; s.state = DHCPS_STATE_ACK;
} else { } else {
#if DHCPS_DEBUG #if DHCPS_DEBUG
DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n");
#endif #endif
s.state = DHCPS_STATE_NAK; s.state = DHCPS_STATE_NAK;
}
} }
break; break;
case DHCP_OPTION_END: {
is_dhcp_parse_end = true;
}
break;
} }
if (is_dhcp_parse_end) { optptr += opt_len + 2;
break;
}
optptr += optptr[1] + 2;
} }
switch (type) { switch (type) {