Skip to content

Commit f9f234c

Browse files
committed
fix(mdns): Fix API races while adding subtypes for services
Fixes **API race issue** (described in 8a69050) for API mdns_service_subtype_add_for_host()
1 parent 3f97a82 commit f9f234c

File tree

2 files changed

+29
-64
lines changed

2 files changed

+29
-64
lines changed

components/mdns/mdns.c

Lines changed: 29 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5111,9 +5111,6 @@ static void _mdns_free_action(mdns_action_t *action)
51115111
case ACTION_SERVICE_INSTANCE_SET:
51125112
free(action->data.srv_instance.instance);
51135113
break;
5114-
case ACTION_SERVICE_SUBTYPE_ADD:
5115-
free(action->data.srv_subtype_add.subtype);
5116-
break;
51175114
case ACTION_SEARCH_ADD:
51185115
//fallthrough
51195116
case ACTION_SEARCH_SEND:
@@ -5155,9 +5152,6 @@ static void _mdns_free_action(mdns_action_t *action)
51555152
static void _mdns_execute_action(mdns_action_t *action)
51565153
{
51575154
mdns_srv_item_t *a = NULL;
5158-
mdns_service_t *service;
5159-
char *subtype;
5160-
mdns_subtype_t *subtype_item;
51615155

51625156
switch (action->type) {
51635157
case ACTION_SYSTEM_EVENT:
@@ -5187,19 +5181,6 @@ static void _mdns_execute_action(mdns_action_t *action)
51875181
action->data.srv_instance.service->service->instance = action->data.srv_instance.instance;
51885182
_mdns_probe_all_pcbs(&action->data.srv_instance.service, 1, false, false);
51895183

5190-
break;
5191-
case ACTION_SERVICE_SUBTYPE_ADD:
5192-
service = action->data.srv_subtype_add.service->service;
5193-
subtype = action->data.srv_subtype_add.subtype;
5194-
subtype_item = (mdns_subtype_t *)malloc(sizeof(mdns_subtype_t));
5195-
if (!subtype_item) {
5196-
HOOK_MALLOC_FAILED;
5197-
_mdns_free_action(action);
5198-
return;
5199-
}
5200-
subtype_item->subtype = subtype;
5201-
subtype_item->next = service->subtype;
5202-
service->subtype = subtype_item;
52035184
break;
52045185
case ACTION_SERVICES_CLEAR:
52055186
_mdns_send_final_bye(false);
@@ -6213,6 +6194,7 @@ esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char
62136194
MDNS_SERVICE_LOCK();
62146195
esp_err_t ret = ESP_OK;
62156196
char *value = NULL;
6197+
mdns_txt_linked_item_t *new_txt = NULL;
62166198
const char *hostname = host ? host : _mdns_server->hostname;
62176199
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service) && !_str_null_or_empty(proto) && !_str_null_or_empty(key) &&
62186200
!((!value_arg && value_len)), ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
@@ -6223,7 +6205,7 @@ esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char
62236205
mdns_service_t *srv = s->service;
62246206
if (value_len > 0) {
62256207
value = (char *) malloc(value_len);
6226-
ESP_GOTO_ON_FALSE(s, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
6208+
ESP_GOTO_ON_FALSE(value, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
62276209
memcpy(value, value_arg, value_len);
62286210
} else {
62296211
value_len = 0;
@@ -6239,14 +6221,14 @@ esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char
62396221
txt = txt->next;
62406222
}
62416223
if (!txt) {
6242-
txt = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t));
6243-
ESP_GOTO_ON_FALSE(s, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
6244-
txt->key = strdup(key);
6245-
ESP_GOTO_ON_FALSE(txt->key, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
6246-
txt->value = value;
6247-
txt->value_len = value_len;
6248-
txt->next = srv->txt;
6249-
srv->txt = txt;
6224+
new_txt = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t));
6225+
ESP_GOTO_ON_FALSE(new_txt, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
6226+
new_txt->key = strdup(key);
6227+
ESP_GOTO_ON_FALSE(new_txt->key, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
6228+
new_txt->value = value;
6229+
new_txt->value_len = value_len;
6230+
new_txt->next = srv->txt;
6231+
srv->txt = new_txt;
62506232
}
62516233

62526234
_mdns_announce_all_pcbs(&s, 1, false);
@@ -6258,6 +6240,7 @@ esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char
62586240
MDNS_SERVICE_UNLOCK();
62596241
HOOK_MALLOC_FAILED;
62606242
free(value);
6243+
free(new_txt);
62616244
return ret;
62626245
}
62636246

@@ -6346,46 +6329,33 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
63466329
const char *hostname, const char *subtype)
63476330
{
63486331
MDNS_SERVICE_LOCK();
6349-
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) ||
6350-
_str_null_or_empty(subtype)) {
6351-
MDNS_SERVICE_UNLOCK();
6352-
return ESP_ERR_INVALID_ARG;
6353-
}
6332+
esp_err_t ret = ESP_OK;
6333+
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service) && !_str_null_or_empty(proto) &&
6334+
!_str_null_or_empty(subtype), ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
6335+
63546336
mdns_srv_item_t *s = _mdns_get_service_item_instance(instance_name, service, proto, hostname);
6355-
MDNS_SERVICE_UNLOCK();
6356-
if (!s) {
6357-
return ESP_ERR_NOT_FOUND;
6358-
}
6337+
ESP_GOTO_ON_FALSE(s, ESP_ERR_NOT_FOUND, err, TAG, "Service doesn't exist");
63596338

63606339
mdns_subtype_t *srv_subtype = s->service->subtype;
63616340
while (srv_subtype) {
6362-
if (strcmp(srv_subtype->subtype, subtype) == 0) {
6363-
// The same subtype has already been added
6364-
return ESP_ERR_INVALID_ARG;
6365-
}
6341+
ESP_GOTO_ON_FALSE(strcmp(srv_subtype->subtype, subtype) != 0, ESP_ERR_INVALID_ARG, err, TAG, "The same subtype has already been added");
63666342
srv_subtype = srv_subtype->next;
63676343
}
63686344

6369-
mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
6370-
if (!action) {
6371-
HOOK_MALLOC_FAILED;
6372-
return ESP_ERR_NO_MEM;
6373-
}
6374-
6375-
action->type = ACTION_SERVICE_SUBTYPE_ADD;
6376-
action->data.srv_subtype_add.service = s;
6377-
action->data.srv_subtype_add.subtype = strdup(subtype);
6345+
mdns_service_t *srv = s->service;
6346+
mdns_subtype_t *subtype_item = (mdns_subtype_t *)malloc(sizeof(mdns_subtype_t));
6347+
ESP_GOTO_ON_FALSE(subtype_item, ESP_ERR_NO_MEM, err, TAG, "Out of memory");
6348+
subtype_item->subtype = strdup(subtype);
6349+
ESP_GOTO_ON_FALSE(subtype_item->subtype, ESP_ERR_NO_MEM, err, TAG, "Out of memory");
6350+
subtype_item->next = srv->subtype;
6351+
srv->subtype = subtype_item;
63786352

6379-
if (!action->data.srv_subtype_add.subtype) {
6380-
free(action);
6381-
return ESP_ERR_NO_MEM;
6382-
}
6383-
if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) {
6384-
free(action->data.srv_subtype_add.subtype);
6385-
free(action);
6386-
return ESP_ERR_NO_MEM;
6353+
err:
6354+
MDNS_SERVICE_UNLOCK();
6355+
if (ret == ESP_ERR_NO_MEM) {
6356+
HOOK_MALLOC_FAILED;
63876357
}
6388-
return ESP_OK;
6358+
return ret;
63896359
}
63906360

63916361
esp_err_t mdns_service_instance_name_set_for_host(const char *instance_old, const char *service, const char *proto, const char *hostname,

components/mdns/private_include/mdns_private.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ typedef enum {
188188
ACTION_HOSTNAME_SET,
189189
ACTION_INSTANCE_SET,
190190
ACTION_SERVICE_INSTANCE_SET,
191-
ACTION_SERVICE_SUBTYPE_ADD,
192191
ACTION_SERVICES_CLEAR,
193192
ACTION_SEARCH_ADD,
194193
ACTION_SEARCH_SEND,
@@ -444,10 +443,6 @@ typedef struct {
444443
mdns_srv_item_t *service;
445444
char *instance;
446445
} srv_instance;
447-
struct {
448-
mdns_srv_item_t *service;
449-
char *subtype;
450-
} srv_subtype_add;
451446
struct {
452447
mdns_search_once_t *search;
453448
} search_add;

0 commit comments

Comments
 (0)