@@ -310,16 +310,30 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
310
310
option_number = * (* packet_data_pptr + 1 ) + 13 ;
311
311
(* packet_data_pptr )++ ;
312
312
} else if (option_number == 14 ) {
313
- option_number = * (* packet_data_pptr + 2 );
314
- option_number += (* (* packet_data_pptr + 1 ) << 8 ) + 269 ;
315
- (* packet_data_pptr ) += 2 ;
313
+ if (message_left >= 2 ){
314
+ option_number = * (* packet_data_pptr + 2 );
315
+ option_number += (* (* packet_data_pptr + 1 ) << 8 ) + 269 ;
316
+ (* packet_data_pptr ) += 2 ;
317
+ } else {
318
+ /* packet_data_pptr would overflow! */
319
+ tr_error ("sn_coap_parser_options_parse - **packet_data_pptr overflow !" );
320
+ return -1 ;
321
+ }
316
322
}
317
323
/* Option number 15 reserved for payload marker. This is handled as a error! */
318
324
else if (option_number == 15 ) {
319
325
tr_error ("sn_coap_parser_options_parse - invalid option number(15)!" );
320
326
return -1 ;
321
327
}
322
328
329
+ message_left = packet_len - ((* packet_data_pptr ) - packet_data_start_ptr );
330
+
331
+ if (message_left == 0 ){
332
+ /* packet_data_pptr would overflow! */
333
+ tr_error ("sn_coap_parser_options_parse - **packet_data_pptr overflow !" );
334
+ return -1 ;
335
+ }
336
+
323
337
/* Add previous option to option delta and get option number */
324
338
option_number += previous_option_number ;
325
339
@@ -328,9 +342,15 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
328
342
option_len = * (* packet_data_pptr + 1 ) + 13 ;
329
343
(* packet_data_pptr )++ ;
330
344
} else if (option_len == 14 ) {
331
- option_len = * (* packet_data_pptr + 2 );
332
- option_len += (* (* packet_data_pptr + 1 ) << 8 ) + 269 ;
333
- (* packet_data_pptr ) += 2 ;
345
+ if (message_left >= 2 ){
346
+ option_len = * (* packet_data_pptr + 2 );
347
+ option_len += (* (* packet_data_pptr + 1 ) << 8 ) + 269 ;
348
+ (* packet_data_pptr ) += 2 ;
349
+ } else {
350
+ /* packet_data_pptr would overflow! */
351
+ tr_error ("sn_coap_parser_options_parse - **packet_data_pptr overflow while resolving option length!" );
352
+ return -1 ;
353
+ }
334
354
}
335
355
/* Option number length 15 is reserved for the future use - ERROR */
336
356
else if (option_len == 15 ) {
@@ -340,6 +360,8 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
340
360
341
361
message_left = packet_len - (* packet_data_pptr - packet_data_start_ptr );
342
362
363
+
364
+
343
365
/* * * Parse option itself * * */
344
366
/* Some options are handled independently in own functions */
345
367
previous_option_number = option_number ;
@@ -366,6 +388,12 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
366
388
break ;
367
389
}
368
390
391
+ if (message_left < option_len ){
392
+ /* packet_data_pptr would overflow! */
393
+ tr_error ("sn_coap_parser_options_parse - **packet_data_pptr would overflow when parsing options!" );
394
+ return -1 ;
395
+ }
396
+
369
397
/* Parse option */
370
398
switch (option_number ) {
371
399
case COAP_OPTION_CONTENT_FORMAT :
@@ -400,9 +428,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
400
428
tr_error ("sn_coap_parser_options_parse - COAP_OPTION_PROXY_URI allocation failed!" );
401
429
return -1 ;
402
430
}
403
-
404
431
(* packet_data_pptr ) += option_len ;
405
-
406
432
break ;
407
433
408
434
case COAP_OPTION_ETAG :
@@ -581,11 +607,9 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
581
607
if ((* packet_data_pptr - packet_data_start_ptr ) > packet_len ) {
582
608
return -1 ;
583
609
}
584
-
585
610
message_left = packet_len - (* packet_data_pptr - packet_data_start_ptr );
586
611
587
612
}
588
-
589
613
return 0 ;
590
614
}
591
615
0 commit comments