diff --git a/components/mdns/mdns_debug.c b/components/mdns/mdns_debug.c index 8fe0290f8..986365c44 100644 --- a/components/mdns/mdns_debug.c +++ b/components/mdns/mdns_debug.c @@ -258,13 +258,15 @@ void static dbg_packet(const uint8_t *data, size_t len) dbg_printf("%" PRIu32, ttl); dbg_printf("[%u] ", data_len); if (type == MDNS_TYPE_PTR) { - if (!mdns_utils_parse_fqdn(data, data_ptr, name, len)) { + size_t rdata_bound = (size_t)(data_ptr + data_len - data); + if (!mdns_utils_parse_fqdn(data, data_ptr, name, rdata_bound)) { dbg_printf("ERROR: parse PTR\n"); continue; } dbg_printf("%s.%s.%s.%s.\n", name->host, name->service, name->proto, name->domain); } else if (type == MDNS_TYPE_SRV) { - if (!mdns_utils_parse_fqdn(data, data_ptr + MDNS_SRV_FQDN_OFFSET, name, len)) { + size_t rdata_bound = (size_t)(data_ptr + data_len - data); + if (!mdns_utils_parse_fqdn(data, data_ptr + MDNS_SRV_FQDN_OFFSET, name, rdata_bound)) { dbg_printf("ERROR: parse SRV\n"); continue; } diff --git a/components/mdns/mdns_receive.c b/components/mdns/mdns_receive.c index 6bf311351..4518a5d68 100644 --- a/components/mdns/mdns_receive.c +++ b/components/mdns/mdns_receive.c @@ -855,7 +855,8 @@ static void mdns_parse_packet(mdns_rx_packet_t *packet) if (type == MDNS_TYPE_PTR) { mdns_browse_t *browse_for_ptr = mdns_priv_browse_find_ptr(name); - if (!mdns_utils_parse_fqdn(data, data_ptr, name, len)) { + size_t rdata_bound = (size_t)(data_ptr + data_len - data); + if (!mdns_utils_parse_fqdn(data, data_ptr, name, rdata_bound)) { continue;//error } if (browse_for_ptr) { @@ -947,7 +948,8 @@ static void mdns_parse_packet(mdns_rx_packet_t *packet) } } bool is_selfhosted = is_name_selfhosted(name); - if (!mdns_utils_parse_fqdn(data, data_ptr + MDNS_SRV_FQDN_OFFSET, name, len)) { + size_t rdata_bound = (size_t)(data_ptr + data_len - data); + if (!mdns_utils_parse_fqdn(data, data_ptr + MDNS_SRV_FQDN_OFFSET, name, rdata_bound)) { continue; } if (data_ptr + MDNS_SRV_PORT_OFFSET + 1 >= data + len) { diff --git a/components/mdns/mdns_utils.c b/components/mdns/mdns_utils.c index b067a3be4..ae9c34405 100644 --- a/components/mdns/mdns_utils.c +++ b/components/mdns/mdns_utils.c @@ -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 */ @@ -15,7 +15,10 @@ static const char *TAG = "mdns_utils"; static const char *MDNS_DEFAULT_DOMAIN = "local"; static const char *MDNS_SUB_STR = "_sub"; -const uint8_t *mdns_utils_read_fqdn(const uint8_t *packet, const uint8_t *start, mdns_name_t *name, char *buf, size_t packet_len) +#define MDNS_FQDN_MAX_COMPRESSION_DEPTH 16 + +static const uint8_t *mdns_utils_read_fqdn_impl(const uint8_t *packet, const uint8_t *start, mdns_name_t *name, + char *buf, size_t packet_len, unsigned compression_depth) { size_t index = 0; const uint8_t *packet_end = packet + packet_len; @@ -63,7 +66,11 @@ const uint8_t *mdns_utils_read_fqdn(const uint8_t *packet, const uint8_t *start, //reference address can not be after where we are return NULL; } - if (mdns_utils_read_fqdn(packet, packet + address, name, buf, packet_len)) { + if (compression_depth >= MDNS_FQDN_MAX_COMPRESSION_DEPTH) { + return NULL; + } + if (mdns_utils_read_fqdn_impl(packet, packet + address, name, buf, packet_len, + compression_depth + 1)) { return start + index; } return NULL; @@ -72,6 +79,12 @@ const uint8_t *mdns_utils_read_fqdn(const uint8_t *packet, const uint8_t *start, return start + index + 1; } +const uint8_t *mdns_utils_read_fqdn(const uint8_t *packet, const uint8_t *start, mdns_name_t *name, char *buf, + size_t packet_len) +{ + return mdns_utils_read_fqdn_impl(packet, start, name, buf, packet_len, 0); +} + const uint8_t *mdns_utils_parse_fqdn(const uint8_t *packet, const uint8_t *start, mdns_name_t *name, size_t packet_len) { name->parts = 0;