fix(mdns): plug fuzz harness and browse sync memory leaks

Free browse sync pending lists on packet parse errors, tear down async
searches detached by search_finish in the host unit test, and replace
reassigned browse hostnames without leaking the old allocation.
This commit is contained in:
David Cermak
2026-05-27 17:19:05 +02:00
parent 429d7b91a2
commit a8c1dad3ec
6 changed files with 51 additions and 10 deletions
+9
View File
@@ -412,6 +412,14 @@ static void sync_browse_result_link_free(mdns_browse_sync_t *browse_sync)
mdns_mem_free(browse_sync);
}
void mdns_priv_browse_sync_free(mdns_browse_sync_t *browse_sync)
{
if (!browse_sync) {
return;
}
sync_browse_result_link_free(browse_sync);
}
void mdns_priv_browse_action(mdns_action_t *action, mdns_action_subtype_t type)
{
if (type == ACTION_RUN) {
@@ -699,6 +707,7 @@ void mdns_priv_browse_result_add_srv(mdns_browse_t *browse, const char *hostname
!mdns_utils_str_null_or_empty(r->service_type) && !strcasecmp(service, r->service_type) &&
!mdns_utils_str_null_or_empty(r->proto) && !strcasecmp(proto, r->proto)) {
if (mdns_utils_str_null_or_empty(r->hostname) || strcasecmp(hostname, r->hostname)) {
mdns_mem_free((char *)r->hostname);
r->hostname = mdns_mem_strdup(hostname);
r->port = port;
if (!r->hostname) {
+16
View File
@@ -192,6 +192,22 @@ void mdns_priv_query_start_stop(void)
mdns_priv_service_unlock();
}
void mdns_priv_search_once_free(mdns_search_once_t *search)
{
if (!search) {
return;
}
queueDetach(mdns_search_once_t, s_search_once, search);
mdns_mem_free(search->instance);
mdns_mem_free(search->service);
mdns_mem_free(search->proto);
vSemaphoreDelete(search->done_semaphore);
if (search->result) {
mdns_priv_query_results_free(search->result);
}
mdns_mem_free(search);
}
void mdns_priv_query_free(void)
{
while (s_search_once) {
+1 -1
View File
@@ -1311,7 +1311,7 @@ clear_rx_packet:
mdns_mem_free(browse_result_instance);
mdns_mem_free(browse_result_service);
mdns_mem_free(browse_result_proto);
mdns_mem_free(out_sync_browse);
mdns_priv_browse_sync_free(out_sync_browse);
}
void mdns_priv_receive_action(mdns_action_t *action, mdns_action_subtype_t type)
@@ -52,6 +52,11 @@ typedef struct mdns_browse_staged_ip {
*/
mdns_browse_sync_t *mdns_priv_browse_ensure_sync(mdns_browse_t *browse, mdns_browse_sync_t *sync);
/**
* @brief Free browse sync object and its pending result list
*/
void mdns_priv_browse_sync_free(mdns_browse_sync_t *browse_sync);
/**
* @brief Stage an A/AAAA record to apply after all packet records are parsed
*/
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -24,6 +24,11 @@ void mdns_priv_query_start_stop(void);
*/
void mdns_priv_query_free(void);
/**
* @brief Free one search object (detached or still on the active list)
*/
void mdns_priv_search_once_free(mdns_search_once_t *search);
/**
* @brief Free search results
* @note Called from multiple modules (browser, querier, core)
+14 -8
View File
@@ -11,6 +11,8 @@
#include "mdns.h"
#include "mdns_receive.h"
#include "mdns_responder.h"
#include "mdns_querier.h"
#include "mdns_browser.h"
#include "mdns_mem_caps.h"
esp_err_t mdns_packet_push(esp_ip_addr_t *addr, int port, mdns_if_t tcpip_if, uint8_t*data, size_t len);
@@ -62,16 +64,20 @@ void init_responder(void)
void deinit_responder(void)
{
mdns_query_async_delete(s_a);
mdns_query_async_delete(s_aaaa);
mdns_query_async_delete(s_ptr);
mdns_query_async_delete(s_srv);
mdns_query_async_delete(s_txt);
mdns_browse_delete("_http", "_tcp");
mdns_browse_delete("_scanner", "_tcp");
mdns_browse_delete("_sleep", "_udp");
mdns_priv_search_once_free(s_a);
mdns_priv_search_once_free(s_aaaa);
mdns_priv_search_once_free(s_ptr);
mdns_priv_search_once_free(s_srv);
mdns_priv_search_once_free(s_txt);
mdns_priv_query_free();
mdns_priv_browse_free();
mdns_service_remove_all();
mdns_priv_responder_free();
s_a = NULL;
s_aaaa = NULL;
s_ptr = NULL;
s_srv = NULL;
s_txt = NULL;
}
static void send_packet(bool ip4, bool mdns_port, uint8_t*data, size_t len)