Skip to content

Out of range memory access in MbedOS CoAP library parser - option value length #12927

@mjurczak

Description

@mjurczak

Description of defect

References:

https://github.com/ARMmbed/mbed-os/tree/mbed-os-5.15.3/features/frameworks/mbed-coap

https://github.com/ARMmbed/mbed-coap/tree/v5.1.5

File:

sn_coap_parser.c

Example Traces:
    #0  sn_coap_parser_options_parse()
        sn_coap_parser.c:342
    #1  sn_coap_parser()
        sn_coap_parser.c:161

    #0  sn_coap_parser_options_parse()
        sn_coap_parser.c:346
    #1  sn_coap_parser()
        sn_coap_parser.c:161

Analysis:

If a packet with option length equal to 13 or 14 is set with no extended option length following, access beyond the provided packet buffer is made due to insufficient message length checks:

if (option_len == 13) {
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;
}
}

Before option length processing the message left bytes is calculated including the option delta/option length byte:

message_left = packet_len - ((*packet_data_pptr) - packet_data_start_ptr);

In case of option length set to 13, the extended delta length is accessed in the following line without prior check for buffer out-of-bound condition:

In case of option length set to 14, the extended length bytes are accessed with insufficient out-of-boudnds condition checks. As the message_left variable includes the option length byte, the check will pass malformed frame if there is only one extended length byte following:

if (message_left >= 2){
option_len = *(*packet_data_pptr + 2);
option_len += (*(*packet_data_pptr + 1) << 8) + 269;
(*packet_data_pptr) += 2;

Type:

  • Integer Overflow or Wraparound
  • Out-of-bounds Read

Result:

  • Parsing data out of input bounds
  • Possible crash due out-of-bound memory access

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;
}

sn_coap_parser.c:346__read_buffer_overflow_minimal.log
sn_coap_parser.c:342__read_buffer_overflow_minimal.log

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions