heap-use-after-free in substitute() causes segfault
Brought to you by:
kmatsui
Hi, I found a segmentation fault in mcpp caused by preprocessing the following code:
// mcpp test.c #define T(a,b,c,d,e,f,g,h,i,j,k,l,m) i T(a,b,c,d,e,f,g,h,i,j,k,l,m)
I compiled mcpp with address sanitizer and got the following error dump
================================================================= ==221888==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b000000290 at pc 0x00000042daf6 bp 0x7fff91da0fe0 sp 0x7fff91da0fd8 READ of size 8 at 0x60b000000290 thread T0 #0 0x42daf5 in substitute /tmp/mcpp-code/src/expand.c:1804 #1 0x4233e6 in replace /tmp/mcpp-code/src/expand.c:803 #2 0x41cae5 in expand_std /tmp/mcpp-code/src/expand.c:310 #3 0x403f7b in mcpp_main /tmp/mcpp-code/src/main.c:708 #4 0x403089 in main /tmp/mcpp-code/src/main.c:421 #5 0x7f09ba41ae49 in __libc_start_main ../csu/libc-start.c:314 #6 0x402539 in _start (/tmp/mcpp-code/src/mcpp+0x402539) 0x60b000000290 is located 64 bytes inside of 104-byte region [0x60b000000250,0x60b0000002b8) freed by thread T0 here: #0 0x7f09bafd54d7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127 #1 0x447db6 in get_ch /tmp/mcpp-code/src/support.c:1633 #2 0x425d98 in prescan /tmp/mcpp-code/src/expand.c:1002 #3 0x42302d in replace /tmp/mcpp-code/src/expand.c:777 #4 0x41cae5 in expand_std /tmp/mcpp-code/src/expand.c:310 #5 0x403f7b in mcpp_main /tmp/mcpp-code/src/main.c:708 #6 0x403089 in main /tmp/mcpp-code/src/main.c:421 #7 0x7f09ba41ae49 in __libc_start_main ../csu/libc-start.c:314 previously allocated by thread T0 here: #0 0x7f09bafd57cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145 #1 0x44f2ff in xmalloc /tmp/mcpp-code/src/support.c:2336 #2 0x44e8ad in get_file /tmp/mcpp-code/src/support.c:2280 #3 0x44e68b in unget_string /tmp/mcpp-code/src/support.c:2243 #4 0x42535f in prescan /tmp/mcpp-code/src/expand.c:999 #5 0x42302d in replace /tmp/mcpp-code/src/expand.c:777 #6 0x41cae5 in expand_std /tmp/mcpp-code/src/expand.c:310 #7 0x403f7b in mcpp_main /tmp/mcpp-code/src/main.c:708 #8 0x403089 in main /tmp/mcpp-code/src/main.c:421 #9 0x7f09ba41ae49 in __libc_start_main ../csu/libc-start.c:314 SUMMARY: AddressSanitizer: heap-use-after-free /tmp/mcpp-code/src/expand.c:1804 in substitute Shadow bytes around the buggy address: 0x0c167fff8000: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x0c167fff8010: fd fd fd fd fd fa fa fa fa fa fa fa fa fa 00 00 0x0c167fff8020: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa 0x0c167fff8030: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 0x0c167fff8040: 00 00 fa fa fa fa fa fa fa fa fd fd fd fd fd fd =>0x0c167fff8050: fd fd[fd]fd fd fd fd fa fa fa fa fa fa fa fa fa 0x0c167fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff80a0: 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 Shadow gap: cc ==221888==ABORTING
Best regards
This actually turned out to be nothing to do with a heap-use-after-free when debugging!
It is caused by get_repl() corrupting the invocation of the 9th or 32nd macro
parameter when it is used at the end of the replacement text, because it sees
the encoded 0x09 or 0x20 formal parameter index as a trailing space to delete.
That corruption then goes on to cause the undefined behavior which results in
a segfault.
I've checked-in a fix for this here ...
https://github.com/jbrandwood/mcpp/commit/f1e1c717840b4a18446d1f26de4f72ebdd105650
Last edit: John Brandwood 2024-03-24