Bug 70498 - Libiberty Demangler segfaults (3)
Summary: Libiberty Demangler segfaults (3)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-01 10:09 UTC by Marcel Böhme
Modified: 2016-05-19 12:06 UTC (History)
2 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcel Böhme 2016-04-01 10:09:01 UTC
Due to the inconsistent use of long and int for string/array length in cp-demangle.c there is an integer overflow that leads to a write access violation. The target crashes on an access violation at an address matching the destination operand of the instruction.

This error was found during fuzzing with a more efficient version of AFL.

How to reproduce:
$ valgrind c++filt _Z80800000000000000000000
==87985== Invalid read of size 1
==87985==    at 0x7C3DFC: d_unqualified_name (cp-demangle.c:1555)
==87985==    by 0x7CA9DF: d_name (cp-demangle.c:1399)
==87985==    by 0x7CC1A3: d_encoding (cp-demangle.c:1257)
==87985==    by 0x7D153C: cplus_demangle_mangled_name (cp-demangle.c:1172)
==87985==    by 0x7D153C: d_demangle_callback (cp-demangle.c:5894)
==87985==    by 0x7D153C: d_demangle (cp-demangle.c:5945)
==87985==    by 0x7D153C: cplus_demangle_v3 (cp-demangle.c:6102)
==87985==    by 0x75AB53: cplus_demangle (cplus-dem.c:865)
..
Segmentation fault

Root cause:
In cp-demangle.c sometimes length-variables are of type long, e.g., when the length of an identifier is parsed in d_number. Other times they are of type int, e.g., when actually parsing an identifier in d_identifier. Note that cp-demangle.h exports structs and methods with length-variables of type int.

Preparing a patch.
Comment 1 Bernd Schmidt 2016-04-08 12:07:31 UTC
Author: bernds
Date: Fri Apr  8 12:06:59 2016
New Revision: 234828

URL: https://gcc.gnu.org/viewcvs?rev=234828&root=gcc&view=rev
Log:
Handle an overflow case (PR70498, patch by Marcel Böhme).

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


Modified:
    trunk/libiberty/ChangeLog
    trunk/libiberty/cplus-dem.c
Comment 2 Bernd Schmidt 2016-04-08 12:28:53 UTC
That was the commit for 70492, sorry.
Comment 3 Bernd Schmidt 2016-05-02 17:07:12 UTC
Author: bernds
Date: Mon May  2 17:06:40 2016
New Revision: 235767

URL: https://gcc.gnu.org/viewcvs?rev=235767&root=gcc&view=rev
Log:
Demangler integer overflow fixes from Marcel Böhme.

	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.


Modified:
    trunk/libiberty/ChangeLog
    trunk/libiberty/cp-demangle.c
    trunk/libiberty/testsuite/demangle-expected
Comment 4 Bernd Schmidt 2016-05-02 17:28:21 UTC
Fixed on trunk.
Comment 5 Jakub Jelinek 2016-05-19 08:50:02 UTC
Author: jakub
Date: Thu May 19 08:49:30 2016
New Revision: 236445

URL: https://gcc.gnu.org/viewcvs?rev=236445&root=gcc&view=rev
Log:
	PR c++/70498
	* cp-demangle.c (d_expression_1): Formatting fix.

Modified:
    trunk/libiberty/ChangeLog
    trunk/libiberty/cp-demangle.c
Comment 6 Jakub Jelinek 2016-05-19 08:53:51 UTC
Author: jakub
Date: Thu May 19 08:53:19 2016
New Revision: 236446

URL: https://gcc.gnu.org/viewcvs?rev=236446&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.

Modified:
    branches/gcc-6-branch/libiberty/ChangeLog
    branches/gcc-6-branch/libiberty/cp-demangle.c
    branches/gcc-6-branch/libiberty/testsuite/demangle-expected
Comment 7 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 8 Jakub Jelinek 2016-05-19 12:06:13 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