-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Labels
Description
Description of defect
References:
https://github.com/ARMmbed/mbed-coap/tree/v5.1.5
File:
Analysis:
If a packet with declared token length larger than actually provided
is parsed, read out of the provided input buffer boundaries may occur.
Invalid memory access may occur in sn_coap_protocol_malloc_copy() as there is no check to verify if the arguments are within input buffer boundaries:
mbed-os/features/frameworks/mbed-coap/source/sn_coap_parser.c
Lines 279 to 288 in b6370b4
/* Parse token, if exists */ | |
dst_coap_msg_ptr->token_len = *packet_data_start_ptr & COAP_HEADER_TOKEN_LENGTH_MASK; | |
if (dst_coap_msg_ptr->token_len) { | |
if ((dst_coap_msg_ptr->token_len > 8) || dst_coap_msg_ptr->token_ptr) { | |
tr_error("sn_coap_parser_options_parse - token not valid!"); | |
return -1; | |
} | |
dst_coap_msg_ptr->token_ptr = sn_coap_protocol_malloc_copy(handle, *packet_data_pptr, dst_coap_msg_ptr->token_len); |
Type:
- Out-of-bounds Read
Result:
- Parsing data out of input bounds
- Possible crash due out-of-bound memory access
Patch proposal:
https://github.com/mjurczak/mbed-coap/tree/bugfix/buffer_read_out_of_bounds
Target(s) affected by this defect ?
- MbedOS mbed-coap library 5.1.5
- MbedOS 5.15.3
Toolchain(s) (name and version) displaying this defect ?
N/A
What version of Mbed-os are you using (tag or sha) ?
MbedOS 5.15.3
What version(s) of tools are you using. List all that apply (E.g. mbed-cli)
N/A
How is this defect reproduced ?
Parsing the provided input example input with sn_coap_parser() function.
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "sn_coap_protocol.h"
#include "sn_coap_header.h"
struct coap_s* coapHandle;
coap_version_e coapVersion = COAP_VERSION_1;
void* coap_malloc(uint16_t size){
return malloc(size);
}
void coap_free(void* addr){
free(addr);
}
uint8_t coap_tx_cb(uint8_t *arg_a, uint16_t arg_b, sn_nsdl_addr_s *arg_c, void *arg_d){
return 0;
}
int8_t coap_rx_cb(sn_coap_hdr_s *arg_a, sn_nsdl_addr_s *arg_b, void *arg_c){
return 0;
}
int main(int argc, const char* argv[])
{
FILE *fp;
size_t read_bytes;
size_t input_size;
uint8_t *message_buffer;
if (argc != 2)
{
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL)
{
return 2;
}
fseek (fp , 0 , SEEK_END);
input_size = ftell(fp);
rewind (fp);
if (input_size > 65527)
{
return 3;
}
message_buffer = malloc(input_size);
read_bytes = fread(message_buffer, 1, input_size, fp);
fclose(fp);
coapHandle = sn_coap_protocol_init(&coap_malloc, &coap_free, &coap_tx_cb, &coap_rx_cb);
sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, read_bytes, message_buffer, &coapVersion);
sn_coap_parser_release_allocated_coap_msg_mem(coapHandle, parsed);
free(message_buffer);
return 0;
}
AshUK