Skip to content

Commit 450cbf0

Browse files
mdns: fix possible crash when packet scheduled to transmit contained service which might have been already removed
packets scheduled to transmit are pushed to action queue and removed from tx_queue_head structure, which is searched for all remaining services and while service is removed, then service questions/asnwers are also removed from this structure. This update fixes possible crash when packet is pushed to action queue, and when service is removed, its answers are removed from tx_queue_head, but not from action queue. this could lead to a crash when the packet is poped from action queue containing questions/answers to already removed (freed) service Closes IDF-504 * Original commit: espressif/esp-idf@67051a2
1 parent 34f6d8d commit 450cbf0

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

components/mdns/mdns.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3819,7 +3819,17 @@ static void _mdns_execute_action(mdns_action_t * action)
38193819
_mdns_search_finish(action->data.search_add.search);
38203820
break;
38213821
case ACTION_TX_HANDLE:
3822-
_mdns_tx_handle_packet(action->data.tx_handle.packet);
3822+
{
3823+
mdns_tx_packet_t * p = _mdns_server->tx_queue_head;
3824+
// packet to be handled should be at tx head, but must be consistent with the one pushed to action queue
3825+
if (p && p==action->data.tx_handle.packet && p->queued) {
3826+
p->queued = false; // clearing, as the packet might be reused (pushed and transmitted again)
3827+
_mdns_server->tx_queue_head = p->next;
3828+
_mdns_tx_handle_packet(p);
3829+
} else {
3830+
ESP_LOGD(TAG, "Skipping transmit of an unexpected packet!");
3831+
}
3832+
}
38233833
break;
38243834
case ACTION_RX_HANDLE:
38253835
mdns_parse_packet(action->data.rx_handle.packet);
@@ -3856,26 +3866,34 @@ static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_o
38563866

38573867
/**
38583868
* @brief Called from timer task to run mDNS responder
3869+
*
3870+
* periodically checks first unqueued packet (from tx head).
3871+
* if it is scheduled to be transmitted, then pushes the packet to action queue to be handled.
3872+
*
38593873
*/
38603874
static void _mdns_scheduler_run()
38613875
{
38623876
MDNS_SERVICE_LOCK();
38633877
mdns_tx_packet_t * p = _mdns_server->tx_queue_head;
38643878
mdns_action_t * action = NULL;
38653879

3880+
// find first unqueued packet
3881+
while (p && p->queued) {
3882+
p = p->next;
3883+
}
38663884
if (!p) {
38673885
MDNS_SERVICE_UNLOCK();
38683886
return;
38693887
}
38703888
if ((int32_t)(p->send_at - (xTaskGetTickCount() * portTICK_PERIOD_MS)) < 0) {
38713889
action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
38723890
if (action) {
3873-
_mdns_server->tx_queue_head = p->next;
38743891
action->type = ACTION_TX_HANDLE;
38753892
action->data.tx_handle.packet = p;
3893+
p->queued = true;
38763894
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
38773895
free(action);
3878-
_mdns_server->tx_queue_head = p;
3896+
p->queued = false;
38793897
}
38803898
} else {
38813899
HOOK_MALLOC_FAILED;

components/mdns/private_include/mdns_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ typedef struct mdns_tx_packet_s {
289289
mdns_out_answer_t * answers;
290290
mdns_out_answer_t * servers;
291291
mdns_out_answer_t * additional;
292+
bool queued;
292293
} mdns_tx_packet_t;
293294

294295
typedef struct {

0 commit comments

Comments
 (0)