• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Révisiond81bf7ddc2ad497037fbfde5d15cfa8d81a9e959 (tree)
l'heure2015-11-29 01:39:29
AuteurMikhail Maltsev <maltsevm@gmai...>
CommiterPedro Alves

Message de Log

Fix several crashes of C++ demangler on fuzzed input.

libiberty/
* cp-demangle.c (d_dump): Fix syntax error.
(d_identifier): Adjust type of len to match d_source_name.
(d_expression_1): Fix out-of-bounds access. Check code variable for
NULL before dereferencing it.
(d_find_pack): Do not recurse for FIXED_TYPE, DEFAULT_ARG and NUMBER.
(d_print_comp_inner): Add NULL pointer check.
* cp-demangle.h (d_peek_next_char): Define as inline function when
CHECK_DEMANGLER is defined.
(d_advance): Likewise.
* testsuite/demangle-expected: Add new testcases.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225727 138bc75d-0d04-0410-961f-82ee72b054a4

Change Summary

Modification

--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -52,6 +52,19 @@
5252
5353 * configure: Regenerated.
5454
55+2015-07-13 Mikhail Maltsev <maltsevm@gmail.com>
56+
57+ * cp-demangle.c (d_dump): Fix syntax error.
58+ (d_identifier): Adjust type of len to match d_source_name.
59+ (d_expression_1): Fix out-of-bounds access. Check code variable for
60+ NULL before dereferencing it.
61+ (d_find_pack): Do not recurse for FIXED_TYPE, DEFAULT_ARG and NUMBER.
62+ (d_print_comp_inner): Add NULL pointer check.
63+ * cp-demangle.h (d_peek_next_char): Define as inline function when
64+ CHECK_DEMANGLER is defined.
65+ (d_advance): Likewise.
66+ * testsuite/demangle-expected: Add new testcases.
67+
5568 2015-07-09 Uros Bizjak <ubizjak@gmail.com>
5669
5770 * getruntime.c (RUSAGE_SELF): Define if not already defined.
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -93,7 +93,11 @@
9393 CP_DEMANGLE_DEBUG
9494 If defined, turns on debugging mode, which prints information on
9595 stdout about the mangled string. This is not generally useful.
96-*/
96+
97+ CHECK_DEMANGLER
98+ If defined, additional sanity checks will be performed. It will
99+ cause some slowdown, but will allow to catch out-of-bound access
100+ errors earlier. This macro is intended for testing and debugging. */
97101
98102 #if defined (_AIX) && !defined (__GNUC__)
99103 #pragma alloca
@@ -419,7 +423,7 @@ static struct demangle_component *d_source_name (struct d_info *);
419423
420424 static long d_number (struct d_info *);
421425
422-static struct demangle_component *d_identifier (struct d_info *, int);
426+static struct demangle_component *d_identifier (struct d_info *, long);
423427
424428 static struct demangle_component *d_operator_name (struct d_info *);
425429
@@ -715,7 +719,7 @@ d_dump (struct demangle_component *dc, int indent)
715719 case DEMANGLE_COMPONENT_FIXED_TYPE:
716720 printf ("fixed-point type, accum? %d, sat? %d\n",
717721 dc->u.s_fixed.accum, dc->u.s_fixed.sat);
718- d_dump (dc->u.s_fixed.length, indent + 2)
722+ d_dump (dc->u.s_fixed.length, indent + 2);
719723 break;
720724 case DEMANGLE_COMPONENT_ARGLIST:
721725 printf ("argument list\n");
@@ -1664,7 +1668,7 @@ d_number_component (struct d_info *di)
16641668 /* identifier ::= <(unqualified source code identifier)> */
16651669
16661670 static struct demangle_component *
1667-d_identifier (struct d_info *di, int len)
1671+d_identifier (struct d_info *di, long len)
16681672 {
16691673 const char *name;
16701674
@@ -1685,7 +1689,7 @@ d_identifier (struct d_info *di, int len)
16851689 /* Look for something which looks like a gcc encoding of an
16861690 anonymous namespace, and replace it with a more user friendly
16871691 name. */
1688- if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
1692+ if (len >= (long) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
16891693 && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
16901694 ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
16911695 {
@@ -3174,6 +3178,8 @@ d_expression_1 (struct d_info *di)
31743178 struct demangle_component *type = NULL;
31753179 if (peek == 't')
31763180 type = cplus_demangle_type (di);
3181+ if (!d_peek_next_char (di))
3182+ return NULL;
31773183 d_advance (di, 2);
31783184 return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
31793185 type, d_exprlist (di, 'E'));
@@ -3248,6 +3254,8 @@ d_expression_1 (struct d_info *di)
32483254 struct demangle_component *left;
32493255 struct demangle_component *right;
32503256
3257+ if (code == NULL)
3258+ return NULL;
32513259 if (op_is_new_cast (op))
32523260 left = cplus_demangle_type (di);
32533261 else
@@ -3275,7 +3283,9 @@ d_expression_1 (struct d_info *di)
32753283 struct demangle_component *second;
32763284 struct demangle_component *third;
32773285
3278- if (!strcmp (code, "qu"))
3286+ if (code == NULL)
3287+ return NULL;
3288+ else if (!strcmp (code, "qu"))
32793289 {
32803290 /* ?: expression. */
32813291 first = d_expression_1 (di);
@@ -4204,6 +4214,9 @@ d_find_pack (struct d_print_info *dpi,
42044214 case DEMANGLE_COMPONENT_CHARACTER:
42054215 case DEMANGLE_COMPONENT_FUNCTION_PARAM:
42064216 case DEMANGLE_COMPONENT_UNNAMED_TYPE:
4217+ case DEMANGLE_COMPONENT_FIXED_TYPE:
4218+ case DEMANGLE_COMPONENT_DEFAULT_ARG:
4219+ case DEMANGLE_COMPONENT_NUMBER:
42074220 return NULL;
42084221
42094222 case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
@@ -4439,6 +4452,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
44394452 local_name = d_right (typed_name);
44404453 if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
44414454 local_name = local_name->u.s_unary_num.sub;
4455+ if (local_name == NULL)
4456+ {
4457+ d_print_error (dpi);
4458+ return;
4459+ }
44424460 while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
44434461 || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
44444462 || local_name->type == DEMANGLE_COMPONENT_CONST_THIS
--- a/libiberty/cp-demangle.h
+++ b/libiberty/cp-demangle.h
@@ -135,12 +135,37 @@ struct d_info
135135 - call d_check_char(di, '\0')
136136 Everything else is safe. */
137137 #define d_peek_char(di) (*((di)->n))
138-#define d_peek_next_char(di) ((di)->n[1])
139-#define d_advance(di, i) ((di)->n += (i))
138+#ifndef CHECK_DEMANGLER
139+# define d_peek_next_char(di) ((di)->n[1])
140+# define d_advance(di, i) ((di)->n += (i))
141+#endif
140142 #define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
141143 #define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
142144 #define d_str(di) ((di)->n)
143145
146+#ifdef CHECK_DEMANGLER
147+static inline char
148+d_peek_next_char (const struct d_info *di)
149+{
150+ if (!di->n[0])
151+ abort ();
152+ return di->n[1];
153+}
154+
155+static inline void
156+d_advance (struct d_info *di, int i)
157+{
158+ if (i < 0)
159+ abort ();
160+ while (i--)
161+ {
162+ if (!di->n[0])
163+ abort ();
164+ di->n++;
165+ }
166+}
167+#endif
168+
144169 /* Functions and arrays in cp-demangle.c which are referenced by
145170 functions in cp-demint.c. */
146171 #ifdef IN_GLIBCPP_V3
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4091,6 +4091,36 @@ void g<1>(A<1>&, B<static_cast<bool>(1)>&)
40914091 _ZNKSt7complexIiE4realB5cxx11Ev
40924092 std::complex<int>::real[abi:cxx11]() const
40934093 #
4094+# Some more crashes revealed by fuzz-testing:
4095+# Check for NULL pointer when demangling trinary operators
4096+--format=gnu-v3
4097+_Z1fAv32_f
4098+_Z1fAv32_f
4099+# Do not overflow when decoding identifier length
4100+--format=gnu-v3
4101+_Z11111111111
4102+_Z11111111111
4103+# Check out-of-bounds access when decoding braced initializer list
4104+--format=gnu-v3
4105+_ZDTtl
4106+_ZDTtl
4107+# Check for NULL pointer when demangling DEMANGLE_COMPONENT_LOCAL_NAME
4108+--format=gnu-v3
4109+_ZZN1fEEd_lEv
4110+_ZZN1fEEd_lEv
4111+# Handle DEMANGLE_COMPONENT_FIXED_TYPE in d_find_pack
4112+--format=gnu-v3
4113+_Z1fDpDFT_
4114+_Z1fDpDFT_
4115+# Likewise, DEMANGLE_COMPONENT_DEFAULT_ARG
4116+--format=gnu-v3
4117+_Z1fIDpZ1fEd_E
4118+_Z1fIDpZ1fEd_E
4119+# Likewise, DEMANGLE_COMPONENT_NUMBER
4120+--format=gnu-v3
4121+_Z1fDpDv1_c
4122+f((char __vector(1))...)
4123+#
40944124 # Ada (GNAT) tests.
40954125 #
40964126 # Simple test.