Skip to content

Commit

Permalink
Merge pull request #12146 from ristohuhtala/mbed-coap-parser-buffer-o…
Browse files Browse the repository at this point in the history
…verflow

mbed-coap buffer overflow fix
  • Loading branch information
0xc0170 authored Jan 2, 2020
2 parents b8045fb + 82caa90 commit b79da0c
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions features/frameworks/mbed-coap/source/sn_coap_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,30 @@ 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) {
option_number = *(*packet_data_pptr + 2);
option_number += (*(*packet_data_pptr + 1) << 8) + 269;
(*packet_data_pptr) += 2;
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) {
tr_error("sn_coap_parser_options_parse - invalid option number(15)!");
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;

Expand All @@ -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) {
option_len = *(*packet_data_pptr + 2);
option_len += (*(*packet_data_pptr + 1) << 8) + 269;
(*packet_data_pptr) += 2;
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) {
Expand All @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit b79da0c

Please sign in to comment.