Bug 70492

Summary: Libiberty Demangler segfaults (2)
Product: gcc Reporter: Marcel Böhme <boehme.marcel>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: bernds, webrown.cpp
Priority: P3    
Version: unknown   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Marcel Böhme 2016-04-01 02:51:22 UTC
Valgrind reports an invalid write of size 8 due to an integer overflow in the demangling of virtual tables in method gnu_special.

How to Reproduce:
$ valgrind c++filt __vt_90000000000cafebabe
==69112== Invalid write of size 8
==69112==    at 0x4C2F793: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==69112==    by 0x781F4A: memcpy (string3.h:51)
==69112==    by 0x781F4A: string_appendn (cplus-dem.c:4855)
==69112==    by 0x781F4A: gnu_special (cplus-dem.c:3015)
==69112==    by 0x782B3E: internal_cplus_demangle (cplus-dem.c:1191)
==69112==    by 0x74F572: cplus_demangle (cplus-dem.c:887)
==69112==    by 0x406251: demangle_it (cxxfilt.c:62)
==69112==    by 0x40582E: main (cxxfilt.c:227)
==69112==  Address 0x5400060 is 0 bytes after a block of size 32 alloc'd
==69112==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==69112==    by 0x7F919C: xmalloc (xmalloc.c:147)
==69112==    by 0x782367: string_need (cplus-dem.c:4775)
==69112==    by 0x782367: string_appendn (cplus-dem.c:4854)
==69112==    by 0x782367: gnu_special (cplus-dem.c:3015)
==69112==    by 0x782B3E: internal_cplus_demangle (cplus-dem.c:1191)
==69112==    by 0x74F572: cplus_demangle (cplus-dem.c:887)
==69112==    by 0x406251: demangle_it (cxxfilt.c:62)
==69112==    by 0x40582E: main (cxxfilt.c:227)
==69112== 
==69112== Invalid read of size 8
==69112==    at 0x4C2F79E: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==69112==    by 0x781F4A: memcpy (string3.h:51)
==69112==    by 0x781F4A: string_appendn (cplus-dem.c:4855)
==69112==    by 0x781F4A: gnu_special (cplus-dem.c:3015)
==69112==    by 0x782B3E: internal_cplus_demangle (cplus-dem.c:1191)
==69112==    by 0x74F572: cplus_demangle (cplus-dem.c:887)
==69112==    by 0x406251: demangle_it (cxxfilt.c:62)
==69112==    by 0x40582E: main (cxxfilt.c:227)
==69112==  Address 0xfff001000 is not stack'd, malloc'd or (recently) free'd
..
==69112== 
==69112== HEAP SUMMARY:
==69112==     in use at exit: 32 bytes in 1 blocks
==69112==   total heap usage: 1 allocs, 0 frees, 32 bytes allocated
==69112== 
==69112== LEAK SUMMARY:
==69112==    definitely lost: 0 bytes in 0 blocks
==69112==    indirectly lost: 0 bytes in 0 blocks
==69112==      possibly lost: 0 bytes in 0 blocks
==69112==    still reachable: 32 bytes in 1 blocks
==69112==         suppressed: 0 bytes in 0 blocks
==69112== Rerun with --leak-check=full to see details of leaked memory
==69112== 
==69112== For counts of detected and suppressed errors, rerun with: -v
==69112== ERROR SUMMARY: 243 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault

Bug Fix: Handle the special case when consume_count returns -1 due to an integer overflow in gnu_special for the length of the virtual table qualifier.

Preparing a patch.
Comment 1 Marcel Böhme 2016-04-01 03:13:53 UTC
This error was found during fuzzing with a more efficient version of AFL.

Patch and reviews available here: https://gcc.gnu.org/ml/gcc-patches/2016-04/msg00000.html
Comment 2 Bernd Schmidt 2016-04-08 12:28:16 UTC
Fixed. Commit message went to a different PR unfortunately.
Comment 3 Jakub Jelinek 2016-05-19 10:45:03 UTC
Author: jakub
Date: Thu May 19 10:44:31 2016
New Revision: 236452

URL: https://gcc.gnu.org/viewcvs?rev=236452&root=gcc&view=rev
Log:
	Backported from mainline
	2016-05-19  Jakub Jelinek  <jakub@redhat.com>

	PR c++/70498
	* cp-demangle.c (d_expression_1): Formatting fix.

	2016-05-02  Marcel Böhme  <boehme.marcel@gmail.com>

	PR c++/70498
	* cp-demangle.c: Parse numbers as integer instead of long to avoid
	overflow after sanity checks. Include <limits.h> if available.
	(INT_MAX): Define if necessary.
	(d_make_template_param): Takes integer argument instead of long.
	(d_make_function_param): Likewise.
	(d_append_num): Likewise.
	(d_identifier): Likewise.
	(d_number): Parse as and return integer.
	(d_compact_number): Handle overflow.
	(d_source_name): Change variable type to integer for parsed number.
	(d_java_resource): Likewise.
	(d_special_name): Likewise.
	(d_discriminator): Likewise.
	(d_unnamed_type): Likewise.
	* testsuite/demangle-expected: Add regression test cases.

	2016-04-08  Marcel Böhme  <boehme.marcel@gmail.com>

	PR c++/69687
	* cplus-dem.c: Include <limits.h> if available.
	(INT_MAX): Define if necessary.
	(remember_type, remember_Ktype, register_Btype, string_need):
	Abort if we detect cases where we the size of the allocation would
	overflow.

	PR c++/70492
	* cplus-dem.c (gnu_special): Handle case where consume_count returns
	-1.

	2016-03-31  Mikhail Maltsev  <maltsevm@gmail.com>
		    Marcel Bohme  <boehme.marcel@gmail.com>

	PR c++/67394
	PR c++/70481
	* cplus-dem.c (squangle_mop_up): Zero bsize/ksize after freeing
	btypevec/ktypevec.
	* testsuite/demangle-expected: Add coverage tests.

Modified:
    branches/gcc-5-branch/libiberty/ChangeLog
    branches/gcc-5-branch/libiberty/cp-demangle.c
    branches/gcc-5-branch/libiberty/cplus-dem.c
    branches/gcc-5-branch/libiberty/testsuite/demangle-expected
Comment 4 Jakub Jelinek 2016-05-19 12:06:14 UTC
Author: jakub
Date: Thu May 19 12:05:41 2016
New Revision: 236456

URL: https://gcc.gnu.org/viewcvs?rev=236456&root=gcc&view=rev
Log:
	Backported from mainline
	2016-05-19  Jakub Jelinek  <jakub@redhat.com>

	PR c++/70498
	* cp-demangle.c (d_expression_1): Formatting fix.

	2016-05-02  Marcel Böhme  <boehme.marcel@gmail.com>

	PR c++/70498
	* cp-demangle.c: Parse numbers as integer instead of long to avoid
	overflow after sanity checks. Include <limits.h> if available.
	(INT_MAX): Define if necessary.
	(d_make_template_param): Takes integer argument instead of long.
	(d_make_function_param): Likewise.
	(d_append_num): Likewise.
	(d_identifier): Likewise.
	(d_number): Parse as and return integer.
	(d_compact_number): Handle overflow.
	(d_source_name): Change variable type to integer for parsed number.
	(d_java_resource): Likewise.
	(d_special_name): Likewise.
	(d_discriminator): Likewise.
	(d_unnamed_type): Likewise.
	* testsuite/demangle-expected: Add regression test cases.

	2016-04-08  Marcel Böhme  <boehme.marcel@gmail.com>

	PR c++/69687
	* cplus-dem.c: Include <limits.h> if available.
	(INT_MAX): Define if necessary.
	(remember_type, remember_Ktype, register_Btype, string_need):
	Abort if we detect cases where we the size of the allocation would
	overflow.

	PR c++/70492
	* cplus-dem.c (gnu_special): Handle case where consume_count returns
	-1.

	2016-03-31  Mikhail Maltsev  <maltsevm@gmail.com>
		    Marcel Bohme  <boehme.marcel@gmail.com>

	PR c++/67394
	PR c++/70481
	* cplus-dem.c (squangle_mop_up): Zero bsize/ksize after freeing
	btypevec/ktypevec.
	* testsuite/demangle-expected: Add coverage tests.

Modified:
    branches/gcc-4_9-branch/libiberty/ChangeLog
    branches/gcc-4_9-branch/libiberty/cp-demangle.c
    branches/gcc-4_9-branch/libiberty/cplus-dem.c
    branches/gcc-4_9-branch/libiberty/testsuite/demangle-expected