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.
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
That was the commit for 70492, sorry.
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
Fixed on trunk.
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
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
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
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
This was fixed for 4.9.4, 5.4.0, 6.2.0 and later.