Bug 88629 (CVE-2018-20712) - Regression lead to Heap-buffer-overflow problem in function d_expression_1 in cp-demangle.c, as demonstrated by c++filt
Summary: Regression lead to Heap-buffer-overflow problem in function d_expression_1 in...
Status: UNCONFIRMED
Alias: CVE-2018-20712
Product: gcc
Classification: Unclassified
Component: demangler (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-12-28 09:27 UTC by Cheng Wen
Modified: 2021-01-12 11:23 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
POC1 (173 bytes, application/octet-stream)
2018-12-28 09:27 UTC, Cheng Wen
Details
POC2 (178 bytes, application/octet-stream)
2018-12-28 09:27 UTC, Cheng Wen
Details
POC3 (142 bytes, application/octet-stream)
2018-12-28 09:27 UTC, Cheng Wen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Cheng Wen 2018-12-28 09:27:10 UTC
Created attachment 45294 [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
Comment 1 Cheng Wen 2018-12-28 09:27:34 UTC
Created attachment 45295 [details]
POC2
Comment 2 Cheng Wen 2018-12-28 09:27:49 UTC
Created attachment 45296 [details]
POC3
Comment 3 Cheng Wen 2018-12-28 10:23:29 UTC
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;
Comment 4 Cheng Wen 2019-01-11 06:04:12 UTC
Hi, does anyone here to look at this bug?
Comment 5 Cheng Wen 2019-02-01 07:21:12 UTC
This bug got assigned CVE-2018-20712
Comment 6 Christian Biesinger 2019-12-04 23:11:18 UTC
I can't reproduce this on any of the three testcases with today's binutils built with ASAN
Comment 7 Trupti Pardeshi 2020-05-07 12:15:36 UTC
Hi,

May I know, if this bug is going to be fixed in binutils and in which version? 

Any heads up will be appreciated.

Best Regards,
Comment 8 Cheng Wen 2020-05-07 12:49:17 UTC
(In reply to Trupti Pardeshi from comment #7)

> commit ebb8004a18a3808d7197762faf3c5aaeae82371f
> Author: GDB Administrator <gdbadmin@sourceware.org>
> Date:   Wed Dec 19 00:00:21 2018 +0000
> 
>     Automatic date update in version.in
Comment 9 Trupti Pardeshi 2020-06-12 05:14:02 UTC
Hi,

Didn't understand reply given comment#8.

Please, may I know, if this bug is going to be fixed in binutils and in which version? 

Or this will be closed as Not reproduced as per comment#6.

Any heads up will be appreciated.

Best Regards,
Comment 10 Cheng Wen 2020-06-14 11:41:25 UTC
(In reply to Trupti Pardeshi from comment #9)

This bug can be reproduced in the commit version ebb8004a18a3808d7197762faf3c5aaeae82371f.

But now is fixed.
Comment 11 Trupti Pardeshi 2020-06-15 07:54:17 UTC
(In reply to Cheng Wen from comment #10)
> (In reply to Trupti Pardeshi from comment #9)
> 
> This bug can be reproduced in the commit version
> ebb8004a18a3808d7197762faf3c5aaeae82371f.
> 
> But now is fixed.

Thanks for reply Cheng. But could you please help me to know, the version of binutils and version of gcc having the fix of this issue?

Knowing fixed-in version (of binutils and gcc) will be very helpful.

Looking forward for reply.

Many Thanks,
Trupti
Comment 12 prajwapa 2021-01-12 07:44:23 UTC
Could someone please let me know, in which binutils version is this fixed?(In reply to Cheng Wen from comment #10)
> (In reply to Trupti Pardeshi from comment #9)
> 
> This bug can be reproduced in the commit version
> ebb8004a18a3808d7197762faf3c5aaeae82371f.
> 
> But now is fixed.

Could you please let me know, in which binutils version is this fixed?

Thanks.
Comment 13 Nick Clifton 2021-01-12 11:23:41 UTC
(In reply to prajwapa from comment #12)

> Could you please let me know, in which binutils version is this fixed?

Not really.  I can confirm that the test cases do not fail when tested with binutils 2.35 (with sanitization enabled) and with any binutils all the way back to 2.30 if sanitization is not enabled.

Given that the bug was reported in 2018-12 and assuming that it was fixed at some point in the 6 months after that, then the nearest binutils release that would have included the fix is 2.33.

I hope that this helps.

Cheers
  Nick