implement fixes for issues found while fuzz testing

This commit is contained in:
me-no-dev 2017-04-03 16:45:59 +03:00
parent fc15d72038
commit 99d39909c4

View File

@ -269,18 +269,18 @@ esp_err_t _mdns_server_deinit(mdns_server_t * server)
*/ */
static size_t _mdns_server_write(mdns_server_t * server, uint8_t * data, size_t len) static size_t _mdns_server_write(mdns_server_t * server, uint8_t * data, size_t len)
{ {
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (pbt != NULL) { if (pbt == NULL) {
uint8_t* dst = (uint8_t *)pbt->payload; return 0;
memcpy(dst, data, len); }
err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port); uint8_t* dst = (uint8_t *)pbt->payload;
pbuf_free(pbt); memcpy(dst, data, len);
if (err) { err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port);
return 0; pbuf_free(pbt);
} if (err) {
return len; return 0;
} }
return 0; return len;
} }
/* /*
@ -391,11 +391,11 @@ static esp_err_t _mdns_server_add(mdns_server_t * server)
*/ */
static esp_err_t _mdns_server_remove(mdns_server_t * server) static esp_err_t _mdns_server_remove(mdns_server_t * server)
{ {
_mdns_servers[server->tcpip_if] = NULL;
//stop UDP //stop UDP
_mdns_server_deinit(server); _mdns_server_deinit(server);
_mdns_servers[server->tcpip_if] = NULL;
if (xQueueRemoveFromSet(server->queue, _mdns_queue_set) != pdPASS) { if (xQueueRemoveFromSet(server->queue, _mdns_queue_set) != pdPASS) {
return ESP_FAIL; return ESP_FAIL;
} }
@ -1309,11 +1309,13 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
if (questions) { if (questions) {
uint8_t qs = questions; uint8_t qs = questions;
mdns_answer_item_t * answers = NULL; mdns_answer_item_t * answer_items = NULL;
while(qs--) { while(qs--) {
content = _mdns_parse_fqdn(data, content, name); content = _mdns_parse_fqdn(data, content, name);
if (!content) { if (!content) {
answers = 0;
additional = 0;
break;//error break;//error
} }
@ -1323,7 +1325,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
if (!name->service[0] || !name->proto[0]) { if (!name->service[0] || !name->proto[0]) {
if (type == MDNS_TYPE_A || type == MDNS_TYPE_AAAA || type == MDNS_TYPE_ANY) {//send A + AAAA if (type == MDNS_TYPE_A || type == MDNS_TYPE_AAAA || type == MDNS_TYPE_ANY) {//send A + AAAA
if (name->host[0] && server->hostname && server->hostname[0] && !strcmp(name->host, server->hostname)) { if (name->host[0] && server->hostname && server->hostname[0] && !strcmp(name->host, server->hostname)) {
answers = _mdns_add_answer(answers, NULL, MDNS_ANSWER_A); answer_items = _mdns_add_answer(answer_items, NULL, MDNS_ANSWER_A);
} }
} }
continue; continue;
@ -1336,7 +1338,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
mdns_srv_item_t * s = server->services; mdns_srv_item_t * s = server->services;
while(s) { while(s) {
if (s->service->service && s->service->proto) { if (s->service->service && s->service->proto) {
answers = _mdns_add_answer(answers, s->service, MDNS_ANSWER_SDPTR); answer_items = _mdns_add_answer(answer_items, s->service, MDNS_ANSWER_SDPTR);
} }
s = s->next; s = s->next;
} }
@ -1354,7 +1356,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
} }
if (type == MDNS_TYPE_PTR) { if (type == MDNS_TYPE_PTR) {
answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_ALL); answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_ALL);
} else if (type == MDNS_TYPE_TXT) { } else if (type == MDNS_TYPE_TXT) {
//match instance/host //match instance/host
const char * host = (si->service->instance)?si->service->instance const char * host = (si->service->instance)?si->service->instance
@ -1363,7 +1365,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
if (!host || !host[0] || !name->host[0] || strcmp(name->host, host)) { if (!host || !host[0] || !name->host[0] || strcmp(name->host, host)) {
continue; continue;
} }
answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_TXT); answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_TXT);
} else if (type == MDNS_TYPE_SRV) { } else if (type == MDNS_TYPE_SRV) {
//match instance/host //match instance/host
const char * host = (si->service->instance)?si->service->instance const char * host = (si->service->instance)?si->service->instance
@ -1372,16 +1374,16 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
if (!host || !host[0] || !name->host[0] || strcmp(name->host, host)) { if (!host || !host[0] || !name->host[0] || strcmp(name->host, host)) {
continue; continue;
} }
answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_SRV | MDNS_ANSWER_A); answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_SRV | MDNS_ANSWER_A);
} else if (type == MDNS_TYPE_ANY) {//send all } else if (type == MDNS_TYPE_ANY) {//send all
//match host //match host
if (!name->host[0] || !server->hostname || !server->hostname[0] || strcmp(name->host, server->hostname)) { if (!name->host[0] || !server->hostname || !server->hostname[0] || strcmp(name->host, server->hostname)) {
answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_ALL); answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_ALL);
} }
} }
} }
if (answers) { if (answer_items) {
_mdns_send_answers(server, answers); _mdns_send_answers(server, answer_items);
} }
} }
@ -1392,7 +1394,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
while(content < (data + len)) { while(content < (data + len)) {
content = _mdns_parse_fqdn(data, content, name); content = _mdns_parse_fqdn(data, content, name);
if (!content) { if (!content) {
break;//error return;//error
} }
uint16_t type = _mdns_read_u16(content, MDNS_TYPE_OFFSET); uint16_t type = _mdns_read_u16(content, MDNS_TYPE_OFFSET);
uint16_t data_len = _mdns_read_u16(content, MDNS_LEN_OFFSET); uint16_t data_len = _mdns_read_u16(content, MDNS_LEN_OFFSET);
@ -1400,6 +1402,10 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
content = data_ptr + data_len; content = data_ptr + data_len;
if(content > (data + len)){
return;
}
if (type == MDNS_TYPE_PTR) { if (type == MDNS_TYPE_PTR) {
if (!_mdns_parse_fqdn(data, data_ptr, name)) { if (!_mdns_parse_fqdn(data, data_ptr, name)) {
continue;//error continue;//error
@ -1444,6 +1450,9 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
uint16_t i=0,b=0, y; uint16_t i=0,b=0, y;
while(i < data_len) { while(i < data_len) {
uint8_t partLen = data_ptr[i++]; uint8_t partLen = data_ptr[i++];
if((i+partLen) > data_len){
break;//error
}
//check if partLen will fit in the buffer //check if partLen will fit in the buffer
if (partLen > (MDNS_TXT_MAX_LEN - b - 1)) { if (partLen > (MDNS_TXT_MAX_LEN - b - 1)) {
break; break;
@ -1611,12 +1620,11 @@ esp_err_t mdns_set_hostname(mdns_server_t * server, const char * hostname)
} }
MDNS_MUTEX_LOCK(); MDNS_MUTEX_LOCK();
free((char*)server->hostname); free((char*)server->hostname);
server->hostname = (char *)malloc(strlen(hostname)+1); server->hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1);
if (!server->hostname) { if (!server->hostname) {
MDNS_MUTEX_UNLOCK(); MDNS_MUTEX_UNLOCK();
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
strlcpy((char *)server->hostname, hostname, MDNS_NAME_BUF_LEN);
MDNS_MUTEX_UNLOCK(); MDNS_MUTEX_UNLOCK();
return ERR_OK; return ERR_OK;
} }
@ -1631,12 +1639,11 @@ esp_err_t mdns_set_instance(mdns_server_t * server, const char * instance)
} }
MDNS_MUTEX_LOCK(); MDNS_MUTEX_LOCK();
free((char*)server->instance); free((char*)server->instance);
server->instance = (char *)malloc(strlen(instance)+1); server->instance = strndup(instance, MDNS_NAME_BUF_LEN - 1);
if (!server->instance) { if (!server->instance) {
MDNS_MUTEX_UNLOCK(); MDNS_MUTEX_UNLOCK();
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
strlcpy((char *)server->instance, instance, MDNS_NAME_BUF_LEN);
MDNS_MUTEX_UNLOCK(); MDNS_MUTEX_UNLOCK();
return ERR_OK; return ERR_OK;
} }
@ -1812,7 +1819,7 @@ esp_err_t mdns_service_remove_all(mdns_server_t * server)
* MDNS QUERY * MDNS QUERY
* */ * */
uint32_t mdns_query(mdns_server_t * server, const char * service, const char * proto, uint32_t timeout) size_t mdns_query(mdns_server_t * server, const char * service, const char * proto, uint32_t timeout)
{ {
if (!server || !service) { if (!server || !service) {
return 0; return 0;