Merge pull request #12146 from ristohuhtala/mbed-coap-parser-buffer-overflow

mbed-coap buffer overflow fix
pull/12183/head
Martin Kojtal 2020-01-02 13:50:52 +00:00 committed by GitHub
commit b79da0c7f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 34 additions and 10 deletions

View File

@ -310,9 +310,15 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
option_number = *(*packet_data_pptr + 1) + 13;
(*packet_data_pptr)++;
} else if (option_number == 14) {
if (message_left >= 2){
option_number = *(*packet_data_pptr + 2);
option_number += (*(*packet_data_pptr + 1) << 8) + 269;
(*packet_data_pptr) += 2;
} else {
/* packet_data_pptr would overflow! */
tr_error("sn_coap_parser_options_parse - **packet_data_pptr overflow !");
return -1;
}
}
/* Option number 15 reserved for payload marker. This is handled as a error! */
else if (option_number == 15) {
@ -320,6 +326,14 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
return -1;
}
message_left = packet_len - ((*packet_data_pptr) - packet_data_start_ptr);
if (message_left == 0){
/* packet_data_pptr would overflow! */
tr_error("sn_coap_parser_options_parse - **packet_data_pptr overflow !");
return -1;
}
/* Add previous option to option delta and get option number */
option_number += previous_option_number;
@ -328,9 +342,15 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
option_len = *(*packet_data_pptr + 1) + 13;
(*packet_data_pptr)++;
} else if (option_len == 14) {
if (message_left >= 2){
option_len = *(*packet_data_pptr + 2);
option_len += (*(*packet_data_pptr + 1) << 8) + 269;
(*packet_data_pptr) += 2;
} else {
/* packet_data_pptr would overflow! */
tr_error("sn_coap_parser_options_parse - **packet_data_pptr overflow while resolving option length!");
return -1;
}
}
/* Option number length 15 is reserved for the future use - ERROR */
else if (option_len == 15) {
@ -340,6 +360,8 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
message_left = packet_len - (*packet_data_pptr - packet_data_start_ptr);
/* * * Parse option itself * * */
/* Some options are handled independently in own functions */
previous_option_number = option_number;
@ -366,6 +388,12 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
break;
}
if (message_left < option_len){
/* packet_data_pptr would overflow! */
tr_error("sn_coap_parser_options_parse - **packet_data_pptr would overflow when parsing options!");
return -1;
}
/* Parse option */
switch (option_number) {
case COAP_OPTION_CONTENT_FORMAT:
@ -400,9 +428,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
tr_error("sn_coap_parser_options_parse - COAP_OPTION_PROXY_URI allocation failed!");
return -1;
}
(*packet_data_pptr) += option_len;
break;
case COAP_OPTION_ETAG:
@ -581,11 +607,9 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack
if ((*packet_data_pptr - packet_data_start_ptr) > packet_len) {
return -1;
}
message_left = packet_len - (*packet_data_pptr - packet_data_start_ptr);
}
return 0;
}