heap buffer overflow is expected
Opened this issue · 4 comments
Hello.
While i'm writing a code with mpc.c, address sanitizer reported a heap buffer overflow.
I attached a file. (both bug1.c and bug2.c can cause heap buffer overflow. please test them separately.)
commit number : 3c26618
And the build command I used is below.
clang -fsanitize=address -m32 -g -ansi -pedantic -O3 -Wall -Wextra -Wformat=2 -Wshadow -Wno-long-long -Wno-overlength-strings -Wno-format-nonliteral -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wredundant-decls -Wnested-externs -Wmissing-include-dirs -Wswitch-default -o bug1 bug1.c ./mpc.c && ./bug1
clang -fsanitize=address -m32 -g -ansi -pedantic -O3 -Wall -Wextra -Wformat=2 -Wshadow -Wno-long-long -Wno-overlength-strings -Wno-format-nonliteral -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wredundant-decls -Wnested-externs -Wmissing-include-dirs -Wswitch-default -o bug2 bug2.c ./mpc.c && ./bug2
It may my problem because I didn't fully understand this code, but anyway please check this.
Hi yuweol,
Thanks for the report. There could be a memory bug in mpc however I can see some bugs in your code which are probably worth fixing first:
In bug1.c
you don't free the result of mpc_parse
which is stored in r
. Either it will be a mpc_err_t
or a mpc_ast_t
you need to check the return code of mpc_parse
to see. You can see an example of this in the code in the quickstart: https://github.com/orangeduck/mpc#quickstart . Also you don't ever free the string bug1
you allocate.
In bug2.c
you don't free any of the parsers you allocate - this needs to be done with mpc_cleanup(4, Expr, Prod, Value, Maths);
like in the quickstart example again.
Finally, I also sometimes get heap memory errors when using mpc which come from inside functions such as strcmp
and strcpy
. The reason for this is that sometimes when these functions are compiled using optimizations they use SIMD instructions which read or write past the end of the allocation. It depends a bit on the exact nature of the report but in most cases these heap memory errors can be ignored because these optimizations are performed in a safe way (by making some basic assumptions about allocation sizes etc).
If you attach the full report/output I can take a closer look.
Hope that helps,
Dan
Hello, Thanks for your reply.
My 2 code files are just examples for reproducing bugs inside mpc.
Below is bug report of address sanitizer, and at this time I compiled the code with option -O0 (without any optimization)
<bug1.c>
==6458==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf51005ef at pc 0x0817cc32 bp 0xfffac958 sp 0xfffac94c
READ of size 1 at 0xf51005ef thread T0
#0 0x817cc31 in mpcf_strtrimr mpc.c:2135:10
#1 0x816a5f2 in mpc_parse_input mpc.c:1042:13
#2 0x81743ce in mpc_parse mpc.c:1197:7
#3 0x81654a3 in main bug1.c:12:3
#4 0xf7495285 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18285)
#5 0x8064237 in _start (bug1+0x8064237)
0xf51005ef is located 1 bytes to the left of 1-byte region [0xf51005f0,0xf51005f1)
allocated by thread T0 here:
#0 0x812a824 in calloc (bug1+0x812a824)
#1 0x817978e in mpcf_strfold mpc.c:2305:13
#2 0x81737d1 in mpc_stack_merger_out mpc.c:939:18
#3 0x816c014 in mpc_parse_input mpc.c:1105:13
#4 0x81743ce in mpc_parse mpc.c:1197:7
#5 0x81654a3 in main bug1.c:12:3
#6 0xf7495285 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18285)
SUMMARY: AddressSanitizer: heap-buffer-overflow mpc.c:2135:10 in mpcf_strtrimr
Shadow bytes around the buggy address:
0x3ea20060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea20070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea20080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea20090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea200a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea200b0: fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]01 fa
0x3ea200c0: fa fa 00 06 fa fa 04 fa fa fa 07 fa fa fa fd fd
0x3ea200d0: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
0x3ea200e0: fa fa fd fd fa fa fd fa fa fa 01 fa fa fa 07 fa
0x3ea200f0: fa fa 00 06 fa fa 00 07 fa fa fa fa fa fa fa fa
0x3ea20100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==6458==ABORTING
<bug2.c>
==7438==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5020314 at pc 0x08129b01 bp 0xff9e9968 sp 0xff9e9540
READ of size 8 at 0xf5020314 thread T0
#0 0x8129b00 in __asan_memmove (bug2+0x8129b00)
#1 0x818b409 in mpc_optimise_unretained mpc.c:3426:7
#2 0x8188d23 in mpc_optimise_unretained mpc.c:3358:7
#3 0x817c916 in mpc_optimise mpc.c:3505:3
#4 0x8194d04 in mpca_stmt_list_apply_to mpc.c:3109:5
#5 0x816a9c4 in mpc_parse_input mpc.c:1052:13
#6 0x8186894 in mpca_lang_st mpc.c:3180:8
#7 0x8186f68 in mpca_lang mpc.c:3250:9
#8 0x81653e6 in main bug2.c:12:3
#9 0xf7575285 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18285)
#10 0x8064237 in _start (bug2+0x8064237)
0xf5020314 is located 0 bytes to the right of 4-byte region [0xf5020310,0xf5020314)
allocated by thread T0 here:
#0 0x812a624 in malloc (bug2+0x812a624)
#1 0x8184013 in mpca_and mpc.c:2780:21
#2 0x8184f74 in mpcaf_grammar_and mpc.c:2857:30
#3 0x81736b1 in mpc_stack_merger_out mpc.c:939:18
#4 0x816c674 in mpc_parse_input mpc.c:1121:15
#5 0x8186894 in mpca_lang_st mpc.c:3180:8
#6 0x8186f68 in mpca_lang mpc.c:3250:9
#7 0x81653e6 in main bug2.c:12:3
#8 0xf7575285 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18285)
SUMMARY: AddressSanitizer: heap-buffer-overflow (bug2+0x8129b00) in __asan_memmove
Shadow bytes around the buggy address:
0x3ea04010: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x3ea04020: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
0x3ea04030: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
0x3ea04040: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fd
0x3ea04050: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fa
=>0x3ea04060: fa fa[04]fa fa fa 00 fa fa fa fd fa fa fa fd fa
0x3ea04070: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x3ea04080: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x3ea04090: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fa
0x3ea040a0: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
0x3ea040b0: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==7438==ABORTING
As you can see, address sanitizer found a bug and forcefully terminated a program while each mpc_parse, mpca_lang function was working.
So I don't think this bugs are because of my misuse of mpc.
Thanks.
Thanks for the full report I will look into it a bit more.
I wasn't able to reproduce these crashes. I think I need to use valgrind to get more information on this which means installing Ubuntu however I am still surprised you are getting errors in this case. These sort of examples have been tried and tested many times...