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