Skip to content

Commit a8e1acb

Browse files
committed
fix(mdns): Use after free
1 parent c078c36 commit a8e1acb

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

components/mdns/mdns.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ static void _mdns_free_tx_packet(mdns_tx_packet_t *packet)
15681568
mdns_mem_free((char *)q->host);
15691569
mdns_mem_free((char *)q->service);
15701570
mdns_mem_free((char *)q->proto);
1571-
mdns_mem_free((char *)q->domain);
1571+
// Note: q->domain points to MDNS_DEFAULT_DOMAIN constant, don't free it
15721572
}
15731573
mdns_mem_free(q);
15741574
q = next;
@@ -2078,12 +2078,15 @@ static bool _mdns_append_host_question(mdns_out_question_t **questions, const ch
20782078
q->next = NULL;
20792079
q->unicast = unicast;
20802080
q->type = MDNS_TYPE_ANY;
2081-
q->host = hostname;
2081+
q->host = hostname ? mdns_mem_strndup(hostname, MDNS_NAME_BUF_LEN - 1) : NULL;
20822082
q->service = NULL;
20832083
q->proto = NULL;
20842084
q->domain = MDNS_DEFAULT_DOMAIN;
2085-
q->own_dynamic_memory = false;
2085+
q->own_dynamic_memory = true;
20862086
if (_mdns_question_exists(q, *questions)) {
2087+
if (q->own_dynamic_memory) {
2088+
mdns_mem_free((char *)q->host);
2089+
}
20872090
mdns_mem_free(q);
20882091
} else {
20892092
queueToEnd(mdns_out_question_t, *questions, q);
@@ -2127,12 +2130,17 @@ static mdns_tx_packet_t *_mdns_create_probe_packet(mdns_if_t tcpip_if, mdns_ip_p
21272130
q->next = NULL;
21282131
q->unicast = first;
21292132
q->type = MDNS_TYPE_ANY;
2130-
q->host = _mdns_get_service_instance_name(services[i]->service);
2131-
q->service = services[i]->service->service;
2132-
q->proto = services[i]->service->proto;
2133+
q->host = _mdns_get_service_instance_name(services[i]->service) ? mdns_mem_strndup(_mdns_get_service_instance_name(services[i]->service), MDNS_NAME_BUF_LEN - 1) : NULL;
2134+
q->service = services[i]->service->service ? mdns_mem_strndup(services[i]->service->service, MDNS_NAME_BUF_LEN - 1) : NULL;
2135+
q->proto = services[i]->service->proto ? mdns_mem_strndup(services[i]->service->proto, MDNS_NAME_BUF_LEN - 1) : NULL;
21332136
q->domain = MDNS_DEFAULT_DOMAIN;
2134-
q->own_dynamic_memory = false;
2137+
q->own_dynamic_memory = true;
21352138
if (!q->host || _mdns_question_exists(q, packet->questions)) {
2139+
if (q->own_dynamic_memory) {
2140+
mdns_mem_free((char *)q->host);
2141+
mdns_mem_free((char *)q->service);
2142+
mdns_mem_free((char *)q->proto);
2143+
}
21362144
mdns_mem_free(q);
21372145
continue;
21382146
} else {
@@ -2834,13 +2842,23 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
28342842
&& qs->service && strcmp(qs->service, service->service) == 0
28352843
&& qs->proto && strcmp(qs->proto, service->proto) == 0) {
28362844
q->questions = q->questions->next;
2845+
if (qs->own_dynamic_memory) {
2846+
mdns_mem_free((char *)qs->host);
2847+
mdns_mem_free((char *)qs->service);
2848+
mdns_mem_free((char *)qs->proto);
2849+
}
28372850
mdns_mem_free(qs);
28382851
} else while (qs->next) {
28392852
qsn = qs->next;
28402853
if (qsn->type == MDNS_TYPE_ANY
28412854
&& qsn->service && strcmp(qsn->service, service->service) == 0
28422855
&& qsn->proto && strcmp(qsn->proto, service->proto) == 0) {
28432856
qs->next = qsn->next;
2857+
if (qsn->own_dynamic_memory) {
2858+
mdns_mem_free((char *)qsn->host);
2859+
mdns_mem_free((char *)qsn->service);
2860+
mdns_mem_free((char *)qsn->proto);
2861+
}
28442862
mdns_mem_free(qsn);
28452863
break;
28462864
}
@@ -5017,11 +5035,11 @@ static mdns_tx_packet_t *_mdns_create_search_packet(mdns_search_once_t *search,
50175035
q->next = NULL;
50185036
q->unicast = search->unicast;
50195037
q->type = search->type;
5020-
q->host = search->instance;
5021-
q->service = search->service;
5022-
q->proto = search->proto;
5038+
q->host = search->instance ? mdns_mem_strndup(search->instance, MDNS_NAME_BUF_LEN - 1) : NULL;
5039+
q->service = search->service ? mdns_mem_strndup(search->service, MDNS_NAME_BUF_LEN - 1) : NULL;
5040+
q->proto = search->proto ? mdns_mem_strndup(search->proto, MDNS_NAME_BUF_LEN - 1) : NULL;
50235041
q->domain = MDNS_DEFAULT_DOMAIN;
5024-
q->own_dynamic_memory = false;
5042+
q->own_dynamic_memory = true;
50255043
queueToEnd(mdns_out_question_t, packet->questions, q);
50265044

50275045
if (search->type == MDNS_TYPE_PTR) {

0 commit comments

Comments
 (0)