diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-05-19 12:05:41 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-05-19 12:05:41 +0000 |
commit | d52c2ad8a48875448d6e83f46e3f9add6fcaac41 (patch) | |
tree | ad303cfaac20b033424fb0e3beefe2a5898590b7 | |
parent | 975697e1b3195b0d937a2f83a48f5c29b51fe839 (diff) | |
download | gcc-d52c2ad8a48875448d6e83f46e3f9add6fcaac41.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@236456 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libiberty/ChangeLog | 46 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 52 | ||||
-rw-r--r-- | libiberty/cplus-dem.c | 22 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 20 |
4 files changed, 118 insertions, 22 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index a32a08f0211..e29224eddb7 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,6 +1,52 @@ 2016-05-19 Jakub Jelinek <jakub@redhat.com> 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. + 2015-11-27 Pedro Alves <palves@redhat.com> PR other/61321 diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 3409fcda323..3e3dd98bbe0 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -124,6 +124,13 @@ extern char *alloca (); # endif /* alloca */ #endif /* HAVE_ALLOCA_H */ +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifndef INT_MAX +# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ +#endif + #include "ansidecl.h" #include "libiberty.h" #include "demangle.h" @@ -394,7 +401,7 @@ d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds, struct demangle_component *); static struct demangle_component * -d_make_template_param (struct d_info *, long); +d_make_template_param (struct d_info *, int); static struct demangle_component * d_make_sub (struct d_info *, const char *, int); @@ -417,9 +424,9 @@ static struct demangle_component *d_unqualified_name (struct d_info *); static struct demangle_component *d_source_name (struct d_info *); -static long d_number (struct d_info *); +static int d_number (struct d_info *); -static struct demangle_component *d_identifier (struct d_info *, long); +static struct demangle_component *d_identifier (struct d_info *, int); static struct demangle_component *d_operator_name (struct d_info *); @@ -1111,7 +1118,7 @@ d_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind, /* Add a new template parameter. */ static struct demangle_component * -d_make_template_param (struct d_info *di, long i) +d_make_template_param (struct d_info *di, int i) { struct demangle_component *p; @@ -1127,7 +1134,7 @@ d_make_template_param (struct d_info *di, long i) /* Add a new function parameter. */ static struct demangle_component * -d_make_function_param (struct d_info *di, long i) +d_make_function_param (struct d_info *di, int i) { struct demangle_component *p; @@ -1601,7 +1608,7 @@ d_unqualified_name (struct d_info *di) static struct demangle_component * d_source_name (struct d_info *di) { - long len; + int len; struct demangle_component *ret; len = d_number (di); @@ -1614,12 +1621,12 @@ d_source_name (struct d_info *di) /* number ::= [n] <(non-negative decimal integer)> */ -static long +static int d_number (struct d_info *di) { int negative; char peek; - long ret; + int ret; negative = 0; peek = d_peek_char (di); @@ -1662,7 +1669,7 @@ d_number_component (struct d_info *di) /* identifier ::= <(unqualified source code identifier)> */ static struct demangle_component * -d_identifier (struct d_info *di, long len) +d_identifier (struct d_info *di, int len) { const char *name; @@ -1683,7 +1690,7 @@ d_identifier (struct d_info *di, long len) /* Look for something which looks like a gcc encoding of an anonymous namespace, and replace it with a more user friendly name. */ - if (len >= (long) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2 + if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2 && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX, ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0) { @@ -1851,7 +1858,7 @@ d_java_resource (struct d_info *di) { struct demangle_component *p = NULL; struct demangle_component *next = NULL; - long len, i; + int len, i; char c; const char *str; @@ -1993,7 +2000,7 @@ d_special_name (struct d_info *di) case 'C': { struct demangle_component *derived_type; - long offset; + int offset; struct demangle_component *base_type; derived_type = cplus_demangle_type (di); @@ -2916,10 +2923,10 @@ d_pointer_to_member_type (struct d_info *di) /* <non-negative number> _ */ -static long +static int d_compact_number (struct d_info *di) { - long num; + int num; if (d_peek_char (di) == '_') num = 0; else if (d_peek_char (di) == 'n') @@ -2927,7 +2934,7 @@ d_compact_number (struct d_info *di) else num = d_number (di) + 1; - if (! d_check_char (di, '_')) + if (num < 0 || ! d_check_char (di, '_')) return -1; return num; } @@ -2939,7 +2946,7 @@ d_compact_number (struct d_info *di) static struct demangle_component * d_template_param (struct d_info *di) { - long param; + int param; if (! d_check_char (di, 'T')) return NULL; @@ -3141,9 +3148,10 @@ d_expression_1 (struct d_info *di) } else { - index = d_compact_number (di) + 1; - if (index == 0) + index = d_compact_number (di); + if (index == INT_MAX || index == -1) return NULL; + index++; } return d_make_function_param (di, index); } @@ -3472,7 +3480,7 @@ d_local_name (struct d_info *di) static int d_discriminator (struct d_info *di) { - long discrim; + int discrim; if (d_peek_char (di) != '_') return 1; @@ -3528,7 +3536,7 @@ static struct demangle_component * d_unnamed_type (struct d_info *di) { struct demangle_component *ret; - long num; + int num; if (! d_check_char (di, 'U')) return NULL; @@ -4046,10 +4054,10 @@ d_append_string (struct d_print_info *dpi, const char *s) } static inline void -d_append_num (struct d_print_info *dpi, long l) +d_append_num (struct d_print_info *dpi, int l) { char buf[25]; - sprintf (buf,"%ld", l); + sprintf (buf,"%d", l); d_append_string (dpi, buf); } diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index 52767cc8fde..aace73302cb 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -56,6 +56,13 @@ void * malloc (); void * realloc (); #endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifndef INT_MAX +# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ +#endif + #include <demangle.h> #undef CURRENT_DEMANGLING_STYLE #define CURRENT_DEMANGLING_STYLE work->options @@ -1224,11 +1231,13 @@ squangle_mop_up (struct work_stuff *work) { free ((char *) work -> btypevec); work->btypevec = NULL; + work->bsize = 0; } if (work -> ktypevec != NULL) { free ((char *) work -> ktypevec); work->ktypevec = NULL; + work->ksize = 0; } } @@ -2986,6 +2995,11 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp) success = 1; break; } + else if (n == -1) + { + success = 0; + break; + } } else { @@ -4241,6 +4255,8 @@ remember_type (struct work_stuff *work, const char *start, int len) } else { + if (work -> typevec_size > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> typevec_size *= 2; work -> typevec = XRESIZEVEC (char *, work->typevec, work->typevec_size); @@ -4268,6 +4284,8 @@ remember_Ktype (struct work_stuff *work, const char *start, int len) } else { + if (work -> ksize > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> ksize *= 2; work -> ktypevec = XRESIZEVEC (char *, work->ktypevec, work->ksize); @@ -4297,6 +4315,8 @@ register_Btype (struct work_stuff *work) } else { + if (work -> bsize > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> bsize *= 2; work -> btypevec = XRESIZEVEC (char *, work->btypevec, work->bsize); @@ -4751,6 +4771,8 @@ string_need (string *s, int n) else if (s->e - s->p < n) { tem = s->p - s->b; + if (n > INT_MAX / 2 - tem) + xmalloc_failed (INT_MAX); n += tem; n *= 2; s->b = XRESIZEVEC (char, s->b, n); diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 7038c7d1365..706c0cd760b 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4406,3 +4406,23 @@ void baz<int>(A<sizeof (foo((int)(), (floatcomplex )00000000_00000000))>*) --format=gnu-v3 _Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv X<sizeof ((P(((F)())())).array)>::Type foo<F>() +# +# Tests a use-after-free problem PR70481 + +_Q.__0 +::Q.(void) +# +# Tests a use-after-free problem PR70481 + +_Q10-__9cafebabe. +cafebabe.::-(void) +# +# Tests integer overflow problem PR70492 + +__vt_90000000000cafebabe +__vt_90000000000cafebabe +# +# Tests write access violation PR70498 + +_Z80800000000000000000000 +_Z80800000000000000000000 |