Created attachment 11499 [details] POC1 Hi, there. A Heap-buffer-overflow problem was discovered in function function d_expression_1 in cp-demangle.c of binutils latest code base, too. A crafted ELF input can cause segment faults and I have confirmed them with address sanitizer too. Please use the "./c++filt -t < $POC" to reproduce the bug. Note that this error only occurs in the last code base, maybe this is a regression error. I will show you the commit ID. > $ git log > commit ebb8004a18a3808d7197762faf3c5aaeae82371f > Author: GDB Administrator <gdbadmin@sourceware.org> > Date: Wed Dec 19 00:00:21 2018 +0000 > > Automatic date update in version.in The ASAN dumps the stack trace as follows: > ================================================================= > ==83311==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000059 at pc 0x000000ac9a4b bp 0x7ffeedce2490 sp 0x7ffeedce2488 > READ of size 1 at 0x602000000059 thread T0 > #0 0xac9a4a in d_expression_1 /binutils-gdb/libiberty/./cp-demangle.c:3356:12 > #1 0xab4724 in d_expression /binutils-gdb/libiberty/./cp-demangle.c:3531:9 > #2 0xaacdbe in cplus_demangle_type /binutils-gdb/libiberty/./cp-demangle.c:2615:9 > #3 0xaaab09 in cplus_demangle_type /binutils-gdb/libiberty/./cp-demangle.c:2411:10 > #4 0xaac400 in cplus_demangle_type /binutils-gdb/libiberty/./cp-demangle.c:2568:26 > #5 0xaac400 in cplus_demangle_type /binutils-gdb/libiberty/./cp-demangle.c:2568:26 > #6 0xab8dc1 in d_demangle_callback /binutils-gdb/libiberty/./cp-demangle.c:6289:7 > #7 0xab7d4f in d_demangle /binutils-gdb/libiberty/./cp-demangle.c:6343:12 > #8 0xab7b66 in cplus_demangle_v3 /binutils-gdb/libiberty/./cp-demangle.c:6500:10 > #9 0xa75571 in cplus_demangle /binutils-gdb/libiberty/./cplus-dem.c:881:13 > #10 0xa904ba in demangle_template_value_parm /binutils-gdb/libiberty/./cplus-dem.c:2146:12 > #11 0xa8a190 in demangle_template /binutils-gdb/libiberty/./cplus-dem.c:2331:14 > #12 0xa849c8 in demangle_signature /binutils-gdb/libiberty/./cplus-dem.c:1709:18 > #13 0xa9715e in iterate_demangle_function /binutils-gdb/libiberty/./cplus-dem.c:2761:14 > #14 0xa81759 in demangle_prefix /binutils-gdb/libiberty/./cplus-dem.c:2989:14 > #15 0xa7a694 in internal_cplus_demangle /binutils-gdb/libiberty/./cplus-dem.c:1254:14 > #16 0xa75cbb in cplus_demangle /binutils-gdb/libiberty/./cplus-dem.c:919:9 > #17 0x51518c in demangle_it /binutils-gdb/binutils/cxxfilt.c:66:12 > #18 0x5149e7 in main /binutils-gdb/binutils/cxxfilt.c:288:4 > #19 0x7f702142782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) > #20 0x41ab28 in _start (/binutils-gdb/build/bin/c++filt+0x41ab28) > > 0x602000000059 is located 0 bytes to the right of 9-byte region [0x602000000050,0x602000000059) > allocated by thread T0 here: > #0 0x4daa50 in malloc /home/tangyun/Documents/Git/llvm-6.0.1/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88 > #1 0xb0740f in xmalloc /binutils-gdb/libiberty/./xmalloc.c:147:12 > #2 0xa903af in demangle_template_value_parm /binutils-gdb/libiberty/./cplus-dem.c:2138:18 > #3 0xa8a190 in demangle_template /binutils-gdb/libiberty/./cplus-dem.c:2331:14 > #4 0xa849c8 in demangle_signature /binutils-gdb/libiberty/./cplus-dem.c:1709:18 > #5 0xa9715e in iterate_demangle_function /binutils-gdb/libiberty/./cplus-dem.c:2761:14 > #6 0xa81759 in demangle_prefix /binutils-gdb/libiberty/./cplus-dem.c:2989:14 > #7 0xa7a694 in internal_cplus_demangle /binutils-gdb/libiberty/./cplus-dem.c:1254:14 > #8 0xa75cbb in cplus_demangle /binutils-gdb/libiberty/./cplus-dem.c:919:9 > #9 0x51518c in demangle_it /binutils-gdb/binutils/cxxfilt.c:66:12 > #10 0x5149e7 in main /binutils-gdb/binutils/cxxfilt.c:288:4 > #11 0x7f702142782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) > > SUMMARY: AddressSanitizer: heap-buffer-overflow /binutils-gdb/libiberty/./cp-demangle.c:3356:12 in d_expression_1 > Shadow bytes around the buggy address: > 0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > =>0x0c047fff8000: fa fa 02 fa fa fa 06 fa fa fa 00[01]fa fa fa fa > 0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c047fff8050: 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 > ==83311==ABORTING
Created attachment 11500 [details] POC2
Created attachment 11501 [details] POC3
That 's because "d_advance (di, 2);" in function d_expression_1, it change di->n = di + 2; leading to buffer-over-flow problem. > 3353 d_advance (di, 2); > 3354 if (peek == 't') > 3355 type = cplus_demangle_type (di); > 3356 if (!d_peek_next_char (di)) > 3357 return NULL;
Hi wcventure, Thanks for reporting this problem. Unfortunately the cp-demangle.c source file, although used by the binutils, is actually maintained by the gcc project. Therefore please could you report this bug here: https://gcc.gnu.org/bugzilla/enter_bug.cgi?product=gcc&Bugzilla_remember=on&Bugzilla_restrictlogin=on&GoAheadAndLogIn=Log%20in Cheers Nick
This issue is moved to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88629