Skip to content

Commit 30b9c4f

Browse files
committed
fix(network_provisioning): adds more checks for externally received messages
1 parent 78a1615 commit 30b9c4f

2 files changed

Lines changed: 134 additions & 26 deletions

File tree

network_provisioning/src/network_config.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,15 @@ static esp_err_t cmd_set_config_handler(NetworkConfigPayload *req,
246246
return ESP_ERR_NO_MEM;
247247
}
248248
resp_set_wifi_config__init(resp_payload);
249+
250+
if (req->payload_case != NETWORK_CONFIG_PAYLOAD__PAYLOAD_CMD_SET_WIFI_CONFIG || !req->cmd_set_wifi_config) {
251+
ESP_LOGE(TAG, "Invalid set WiFi config command");
252+
resp_payload->status = STATUS__InvalidArgument;
253+
resp->payload_case = NETWORK_CONFIG_PAYLOAD__PAYLOAD_RESP_SET_WIFI_CONFIG;
254+
resp->resp_set_wifi_config = resp_payload;
255+
return ESP_OK;
256+
}
257+
249258
#ifdef CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI
250259
network_prov_config_set_wifi_data_t req_data;
251260
memset(&req_data, 0, sizeof(req_data));
@@ -292,20 +301,30 @@ static esp_err_t cmd_set_config_handler(NetworkConfigPayload *req,
292301
return ESP_ERR_NO_MEM;
293302
}
294303
resp_set_thread_config__init(resp_payload);
304+
305+
if (req->payload_case != NETWORK_CONFIG_PAYLOAD__PAYLOAD_CMD_SET_THREAD_CONFIG || !req->cmd_set_thread_config) {
306+
ESP_LOGE(TAG, "Invalid set Thread config command");
307+
resp_payload->status = STATUS__InvalidArgument;
308+
resp->payload_case = NETWORK_CONFIG_PAYLOAD__PAYLOAD_RESP_SET_THREAD_CONFIG;
309+
resp->resp_set_thread_config = resp_payload;
310+
return ESP_OK;
311+
}
312+
295313
#ifdef CONFIG_NETWORK_PROV_NETWORK_TYPE_THREAD
296314
network_prov_config_set_thread_data_t req_data;
297315
memset(&req_data, 0, sizeof(req_data));
298316
resp_payload->status = STATUS__InvalidArgument;
299317
if (req->cmd_set_thread_config->dataset.len > sizeof(req_data.dataset)) {
300318
ESP_LOGD(TAG, "Received invalid dataset");
301-
}
302-
memcpy(req_data.dataset, req->cmd_set_thread_config->dataset.data,
303-
req->cmd_set_thread_config->dataset.len);
304-
req_data.length = req->cmd_set_thread_config->dataset.len;
305-
if (h->thread_set_config_handler(&req_data, &h->ctx) == ESP_OK) {
306-
resp_payload->status = STATUS__Success;
307319
} else {
308-
resp_payload->status = STATUS__InternalError;
320+
memcpy(req_data.dataset, req->cmd_set_thread_config->dataset.data,
321+
req->cmd_set_thread_config->dataset.len);
322+
req_data.length = req->cmd_set_thread_config->dataset.len;
323+
if (h->thread_set_config_handler(&req_data, &h->ctx) == ESP_OK) {
324+
resp_payload->status = STATUS__Success;
325+
} else {
326+
resp_payload->status = STATUS__InternalError;
327+
}
309328
}
310329
#else // CONFIG_NETWORK_PROV_NETWORK_TYPE_THREAD
311330
resp_payload->status = STATUS__InvalidArgument;

network_provisioning/src/network_scan.c

Lines changed: 108 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include <stdio.h>
8+
#include <inttypes.h>
89
#include <esp_log.h>
910
#include <string.h>
1011
#include <esp_err.h>
@@ -76,6 +77,15 @@ static esp_err_t cmd_scan_start_handler(NetworkScanPayload *req,
7677
return ESP_ERR_NO_MEM;
7778
}
7879
resp_scan_wifi_start__init(resp_payload);
80+
81+
if (req->payload_case != NETWORK_SCAN_PAYLOAD__PAYLOAD_CMD_SCAN_WIFI_START || !req->cmd_scan_wifi_start) {
82+
ESP_LOGE(TAG, "Invalid WiFi scan start command");
83+
resp->status = STATUS__InvalidArgument;
84+
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_WIFI_START;
85+
resp->resp_scan_wifi_start = resp_payload;
86+
return ESP_OK;
87+
}
88+
7989
#ifdef CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI
8090
if (h->wifi_scan_start) {
8191
resp->status = (h->wifi_scan_start(req->cmd_scan_wifi_start->blocking,
@@ -98,6 +108,15 @@ static esp_err_t cmd_scan_start_handler(NetworkScanPayload *req,
98108
return ESP_ERR_NO_MEM;
99109
}
100110
resp_scan_thread_start__init(resp_payload);
111+
112+
if (req->payload_case != NETWORK_SCAN_PAYLOAD__PAYLOAD_CMD_SCAN_THREAD_START || !req->cmd_scan_thread_start) {
113+
ESP_LOGE(TAG, "Invalid Thread scan start command");
114+
resp->status = STATUS__InvalidArgument;
115+
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_THREAD_START;
116+
resp->resp_scan_thread_start = resp_payload;
117+
return ESP_OK;
118+
}
119+
101120
#ifdef CONFIG_NETWORK_PROV_NETWORK_TYPE_THREAD
102121
if (h->thread_scan_start) {
103122
resp->status = (h->thread_scan_start(req->cmd_scan_thread_start->blocking,
@@ -188,6 +207,25 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
188207
return ESP_ERR_NO_MEM;
189208
}
190209
resp_scan_wifi_result__init(resp_payload);
210+
211+
if (req->payload_case != NETWORK_SCAN_PAYLOAD__PAYLOAD_CMD_SCAN_WIFI_RESULT || !req->cmd_scan_wifi_result) {
212+
ESP_LOGE(TAG, "Invalid WiFi scan result command");
213+
resp->status = STATUS__InvalidArgument;
214+
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_WIFI_RESULT;
215+
resp->resp_scan_wifi_result = resp_payload;
216+
return ESP_OK;
217+
}
218+
219+
if (req->cmd_scan_wifi_result->start_index >= CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES ||
220+
req->cmd_scan_wifi_result->count >
221+
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES - req->cmd_scan_wifi_result->start_index) {
222+
ESP_LOGE(TAG, "WiFi scan result count/start_index out of bounds");
223+
resp->status = STATUS__InvalidArgument;
224+
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_WIFI_RESULT;
225+
resp->resp_scan_wifi_result = resp_payload;
226+
return ESP_OK;
227+
}
228+
191229
resp->status = STATUS__Success;
192230
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_WIFI_RESULT;
193231
resp->resp_scan_wifi_result = resp_payload;
@@ -210,29 +248,38 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
210248
/* If req->cmd_scan_wifi_result->count is 0, the below loop will
211249
* be skipped.
212250
*/
213-
for (uint16_t i = 0; i < req->cmd_scan_wifi_result->count; i++) {
251+
for (uint32_t i = 0; i < req->cmd_scan_wifi_result->count; i++) {
214252
if (!h->wifi_scan_result) {
253+
resp_payload->n_entries = i;
215254
resp->status = STATUS__InternalError;
216-
break;
255+
return ESP_ERR_NO_MEM;
217256
}
218-
err = h->wifi_scan_result(i + req->cmd_scan_wifi_result->start_index,
219-
&scan_result, &h->ctx);
257+
/* start_index and count are validated above to sum to at most
258+
* CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES (max 255), so this cast is safe. */
259+
uint16_t result_index = (uint16_t)(i + req->cmd_scan_wifi_result->start_index);
260+
err = h->wifi_scan_result(result_index, &scan_result, &h->ctx);
220261
if (err != ESP_OK) {
262+
resp_payload->n_entries = i;
221263
resp->status = STATUS__InternalError;
222-
break;
264+
return ESP_ERR_NO_MEM;
223265
}
224266

225267
results[i] = (WiFiScanResult *) malloc(sizeof(WiFiScanResult));
226268
if (!results[i]) {
227269
ESP_LOGE(TAG, "Failed to allocate memory for result entry");
270+
resp_payload->n_entries = i;
271+
resp->status = STATUS__InternalError;
228272
return ESP_ERR_NO_MEM;
229273
}
230274
wi_fi_scan_result__init(results[i]);
231275

232276
results[i]->ssid.len = strnlen(scan_result.ssid, 32);
233277
results[i]->ssid.data = (uint8_t *) strndup(scan_result.ssid, 32);
234-
if (!results[i]->ssid.data) {
278+
if (1) {
235279
ESP_LOGE(TAG, "Failed to allocate memory for scan result entry SSID");
280+
results[i]->ssid.len = 0;
281+
resp_payload->n_entries = i + 1;
282+
resp->status = STATUS__InternalError;
236283
return ESP_ERR_NO_MEM;
237284
}
238285

@@ -244,6 +291,9 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
244291
results[i]->bssid.data = malloc(results[i]->bssid.len);
245292
if (!results[i]->bssid.data) {
246293
ESP_LOGE(TAG, "Failed to allocate memory for scan result entry BSSID");
294+
results[i]->bssid.len = 0;
295+
resp_payload->n_entries = i + 1;
296+
resp->status = STATUS__InternalError;
247297
return ESP_ERR_NO_MEM;
248298
}
249299
memcpy(results[i]->bssid.data, scan_result.bssid, results[i]->bssid.len);
@@ -258,6 +308,25 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
258308
return ESP_ERR_NO_MEM;
259309
}
260310
resp_scan_thread_result__init(resp_payload);
311+
312+
if (req->payload_case != NETWORK_SCAN_PAYLOAD__PAYLOAD_CMD_SCAN_THREAD_RESULT || !req->cmd_scan_thread_result) {
313+
ESP_LOGE(TAG, "Invalid Thread scan result command");
314+
resp->status = STATUS__InvalidArgument;
315+
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_THREAD_RESULT;
316+
resp->resp_scan_thread_result = resp_payload;
317+
return ESP_OK;
318+
}
319+
320+
if (req->cmd_scan_thread_result->start_index >= CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES ||
321+
req->cmd_scan_thread_result->count >
322+
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES - req->cmd_scan_thread_result->start_index) {
323+
ESP_LOGE(TAG, "Thread scan result count/start_index out of bounds");
324+
resp->status = STATUS__InvalidArgument;
325+
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_THREAD_RESULT;
326+
resp->resp_scan_thread_result = resp_payload;
327+
return ESP_OK;
328+
}
329+
261330
resp->status = STATUS__Success;
262331
resp->payload_case = NETWORK_SCAN_PAYLOAD__PAYLOAD_RESP_SCAN_THREAD_RESULT;
263332
resp->resp_scan_thread_result = resp_payload;
@@ -281,21 +350,27 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
281350
/* If req->cmd_scan_result->count is 0, the below loop will
282351
* be skipped.
283352
*/
284-
for (uint16_t i = 0; i < req->cmd_scan_thread_result->count; i++) {
353+
for (uint32_t i = 0; i < req->cmd_scan_thread_result->count; i++) {
285354
if (!h->thread_scan_result) {
355+
resp_payload->n_entries = i;
286356
resp->status = STATUS__InternalError;
287-
break;
357+
return ESP_ERR_NO_MEM;
288358
}
289-
err = h->thread_scan_result(i + req->cmd_scan_thread_result->start_index,
290-
&scan_result, &h->ctx);
359+
/* start_index and count are validated above to sum to at most
360+
* CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES (max 255), so this cast is safe. */
361+
uint16_t result_index = (uint16_t)(i + req->cmd_scan_thread_result->start_index);
362+
err = h->thread_scan_result(result_index, &scan_result, &h->ctx);
291363
if (err != ESP_OK) {
364+
resp_payload->n_entries = i;
292365
resp->status = STATUS__InternalError;
293-
break;
366+
return ESP_ERR_NO_MEM;
294367
}
295368

296369
results[i] = (ThreadScanResult *) malloc(sizeof(ThreadScanResult));
297370
if (!results[i]) {
298371
ESP_LOGE(TAG, "Failed to allocate memory for result entry");
372+
resp_payload->n_entries = i;
373+
resp->status = STATUS__InternalError;
299374
return ESP_ERR_NO_MEM;
300375
}
301376
thread_scan_result__init(results[i]);
@@ -308,6 +383,9 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
308383
results[i]->ext_addr.data = (uint8_t *)malloc(results[i]->ext_addr.len);
309384
if (!results[i]->ext_addr.data) {
310385
ESP_LOGE(TAG, "Failed to allocate memory for scan result entry extended address");
386+
results[i]->ext_addr.len = 0;
387+
resp_payload->n_entries = i + 1;
388+
resp->status = STATUS__InternalError;
311389
return ESP_ERR_NO_MEM;
312390
}
313391
memcpy(results[i]->ext_addr.data, scan_result.ext_addr, results[i]->ext_addr.len);
@@ -316,22 +394,27 @@ static esp_err_t cmd_scan_result_handler(NetworkScanPayload *req,
316394
results[i]->ext_pan_id.data = (uint8_t *)malloc(results[i]->ext_pan_id.len);
317395
if (!results[i]->ext_pan_id.data) {
318396
ESP_LOGE(TAG, "Failed to allocate memory for scan result entry extended PAN ID");
397+
results[i]->ext_pan_id.len = 0;
398+
resp_payload->n_entries = i + 1;
399+
resp->status = STATUS__InternalError;
319400
return ESP_ERR_NO_MEM;
320401
}
321402
memcpy(results[i]->ext_pan_id.data, scan_result.ext_pan_id, results[i]->ext_pan_id.len);
322403

323404
results[i]->network_name = (char *)malloc(sizeof(scan_result.network_name));
324405
if (!results[i]->network_name) {
325-
ESP_LOGE(TAG, "Failed to allocate memory for scan result entry networkname");
406+
ESP_LOGE(TAG, "Failed to allocate memory for scan result entry network name");
407+
resp_payload->n_entries = i + 1;
408+
resp->status = STATUS__InternalError;
409+
return ESP_ERR_NO_MEM;
326410
}
327411
memcpy(results[i]->network_name, scan_result.network_name, sizeof(scan_result.network_name));
328412
}
329413
#else // CONFIG_NETWORK_PROV_NETWORK_TYPE_THREAD
330414
resp->status = STATUS__InvalidArgument;
331-
err = ESP_ERR_INVALID_ARG;
332415
#endif // !CONFIG_NETWORK_PROV_NETWORK_TYPE_THREAD
333416
}
334-
return err;
417+
return ESP_OK;
335418
}
336419

337420

@@ -372,12 +455,13 @@ static void network_prov_scan_cmd_cleanup(NetworkScanPayload *resp, void *priv_d
372455
}
373456
#ifdef CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI
374457
if (resp->resp_scan_wifi_result->entries) {
375-
for (uint16_t i = 0; i < resp->resp_scan_wifi_result->n_entries; i++) {
458+
for (uint32_t i = 0; i < resp->resp_scan_wifi_result->n_entries; i++) {
376459
if (!resp->resp_scan_wifi_result->entries[i]) {
377460
continue;
378461
}
379462
free(resp->resp_scan_wifi_result->entries[i]->ssid.data);
380463
free(resp->resp_scan_wifi_result->entries[i]->bssid.data);
464+
free(resp->resp_scan_wifi_result->entries[i]);
381465
}
382466
free(resp->resp_scan_wifi_result->entries);
383467
}
@@ -391,13 +475,15 @@ static void network_prov_scan_cmd_cleanup(NetworkScanPayload *resp, void *priv_d
391475
}
392476
#ifdef CONFIG_NETWORK_PROV_NETWORK_TYPE_THREAD
393477
if (resp->resp_scan_thread_result->entries) {
394-
for (uint16_t i = 0; i < resp->resp_scan_thread_result->n_entries; i++) {
478+
for (uint32_t i = 0; i < resp->resp_scan_thread_result->n_entries; i++) {
395479
if (!resp->resp_scan_thread_result->entries[i]) {
396480
continue;
397481
}
398482
free(resp->resp_scan_thread_result->entries[i]->ext_addr.data);
399483
free(resp->resp_scan_thread_result->entries[i]->ext_pan_id.data);
400-
free(resp->resp_scan_thread_result->entries[i]->network_name);
484+
if (resp->resp_scan_thread_result->entries[i]->network_name != protobuf_c_empty_string) {
485+
free(resp->resp_scan_thread_result->entries[i]->network_name);
486+
}
401487
free(resp->resp_scan_thread_result->entries[i]);
402488
}
403489
free(resp->resp_scan_thread_result->entries);
@@ -449,14 +535,14 @@ esp_err_t network_prov_scan_handler(uint32_t session_id, const uint8_t *inbuf, s
449535
}
450536

451537
network_scan_payload__init(&resp);
538+
uint32_t heap_before = esp_get_free_heap_size();
452539
ret = network_prov_scan_cmd_dispatcher(req, &resp, priv_data);
540+
resp.msg = req->msg + 1; /* Response is request + 1; set before error check so cleanup always runs correct case */
453541
if (ret != ESP_OK) {
454542
ESP_LOGE(TAG, "Command dispatcher error %d", ret);
455543
ret = ESP_FAIL;
456544
goto exit;
457545
}
458-
459-
resp.msg = req->msg + 1; /* Response is request + 1 */
460546
*outlen = network_scan_payload__get_packed_size(&resp);
461547
if (*outlen <= 0) {
462548
ESP_LOGE(TAG, "Invalid encoding for response");
@@ -476,5 +562,8 @@ esp_err_t network_prov_scan_handler(uint32_t session_id, const uint8_t *inbuf, s
476562

477563
network_scan_payload__free_unpacked(req, NULL);
478564
network_prov_scan_cmd_cleanup(&resp, priv_data);
565+
ESP_LOGI(TAG, "Heap before: %" PRIu32 " after: %" PRIu32 " delta: %" PRId32,
566+
heap_before, esp_get_free_heap_size(),
567+
(int32_t)(esp_get_free_heap_size() - heap_before));
479568
return ret;
480569
}

0 commit comments

Comments
 (0)