contiki-os/contiki

er-coap - memory corruption in coap_parse_message (SIGSEGV)

stze opened this issue · 5 comments

stze commented

Parsing the following coap message results in a crash of contiki:

coap message hexdump:

00000000  42 43 42 42 42 42 42 9e  80 42 42 28 01 e1 e1 e1  |BCBBBBB..BB(....|                          
00000010  e1 e1 e1 e1 e1 e1 e1 e1  e1 e1 e1 bf e1 00 00 10  |................|
00000020  00 43 42 53 42 ff 49                              |.CBSB.I|
00000027

How to reproduce:

static coap_packet_t message[1];
uint8_t teststr[] = { 0x42 ,0x43 ,0x42 ,0x42 ,0x42 ,0x42 ,0x42 ,0x9e ,0x80 ,0x42 ,0x42 ,0x28 ,0x01 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xe1 ,0xbf ,0xe1 ,0x00 ,0x00 ,0x10 ,0x00 ,0x43 ,0x42 ,0x53 ,0x42 ,0xff ,0x49 };
coap_parse_message(message, (unsigned char *)teststr, sizeof(teststr));

gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000000000041464e in coap_parse_message (packet=0x63a240 <message>, data=0x7fff7270aba0 "BCBBBBB\236\200BB(/", '\341' <repeats 14 times>, "\277", <incomplete sequence \341>, data_len=39)
    at ../../apps/er-coap/er-coap.c:537
537	    SET_OPTION(coap_pkt, option_number);
(gdb) bt
#0  0x000000000041464e in coap_parse_message (packet=0x63a240 <message>, data=0x7fff7270aba0 "BCBBBBB\236\200BB(/", '\341' <repeats 14 times>, "\277", <incomplete sequence \341>, data_len=39)
    at ../../apps/er-coap/er-coap.c:537
#1  0x0000000000407828 in process_thread_er_example_client (process_pt=0x639198 <er_example_client+24>, ev=<optimized out>, data=<optimized out>) at er-example-client.c:116
#2  0x000000000041be88 in call_process (p=0x639180 <er_example_client>, ev=129 '\201', data=0x0) at ../../core/sys/process.c:190
#3  0x000000000041b895 in process_post_synch (p=0x639180 <er_example_client>, ev=129 '\201', data=0x0) at ../../core/sys/process.c:366
#4  0x000000000041b853 in process_start (p=0x639180 <er_example_client>, data=0x0) at ../../core/sys/process.c:120
#5  0x000000000041ab8b in autostart_start (processes=0x4305a0 <autostart_processes>) at ../../core/sys/autostart.c:57
#6  0x000000000041a201 in main (argc=1, argv=0x7fff7270af28) at ../../platform/native/./contiki-main.c:247

valgrind:

==4353== Invalid read of size 1
==4353==    at 0x41464E: coap_parse_message (er-coap.c:537)
==4353==    by 0x407827: process_thread_er_example_client (er-example-client.c:116)
==4353==    by 0x41BE87: call_process (process.c:190)
==4353==    by 0x41B894: process_post_synch (process.c:366)
==4353==    by 0x41B852: process_start (process.c:120)
==4353==    by 0x41AB8A: autostart_start (autostart.c:57)
==4353==    by 0x41A200: main (contiki-main.c:247)
==4353==  Address 0x640f95 is not stack'd, malloc'd or (recently) free'd
==4353== 
==4353== 
==4353== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==4353==  Access not within mapped region at address 0x640F95
==4353==    at 0x41464E: coap_parse_message (er-coap.c:537)
==4353==    by 0x407827: process_thread_er_example_client (er-example-client.c:116)
==4353==    by 0x41BE87: call_process (process.c:190)
==4353==    by 0x41B894: process_post_synch (process.c:366)
==4353==    by 0x41B852: process_start (process.c:120)
==4353==    by 0x41AB8A: autostart_start (autostart.c:57)
==4353==    by 0x41A200: main (contiki-main.c:247)

The crash has been found with afl-fuzz.

Best Regards,
Stephan Zeisberg

Ok, yes, we need to fix that. afl-fuzz produce incorrect CoAP packets or is this a correct CoAP packet?
I guess this tool should be a part of the regression testing also, in the long run.

Thanks a lot for reporting!

stze commented

afl-fuzz produce incorrect CoAP packets or is this a correct CoAP packet?

afl-fuzz created this packet and i'm not sure if this is an incorrect CoAP packet. The libcoap function coap_show_pdu outputs the following for the packet.

v:1 t:CON c:2.03 i:4242 {4242} [ ETag:\x9E\x80, Location-Path:B(, Location-Path:\xE1, 58102:\xE1, 50660:\xE1, 43218:\xE1, 27072:\x00, 27072:, 27073:, 27073:, 27077:\x42\x53\x42 ] :: 'I'
nvt commented

Thanks for the report. There is apparently no checking of option number validity in (or preceding) SET_OPTION() in er-coap. afl-fuzz created a packet that had a very high option number to make it crash.

OPTION 223680 (delta 49390, len 1): ==19227== Invalid read of size 1
==19227== at 0x40B282: coap_parse_message (er-coap.c:537)

#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE))

nvt commented

PR #2249 has been merged to fix this issue. Thanks!