Re: [PATCH 10/10] libiberty: Correct an invalid assumption

2019-01-15 Thread Ben L
On 14/01/2019 11:10, Iain Buclaw wrote:

> Thanks, do you have a copyright assignment with the FSF?

No problem, and no I don't think so. I'd assumed these patches were trivial
enough to not need anything like that, but if so then what do I need to do?

> Rather than checking for overflow twice, I think it would be
> sufficient to just do:
> ---
> long digit = mangled[0] - '0';
>
> if (*ret > ((LONG_MAX - digit) / 10))
>return NULL;
>
> (*ret) *= 10;
> (*ret) += digit;
> mangled++;
> ---

I'd agree, that does the trick too. Do I need to resend the patch with that
change, or can that be done by whoever applies it since they'll be squashed
into a single patch anyway?

Thanks,
Ben



[PATCH 10/10] libiberty: Correct an invalid assumption

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

As a counter example: 888 * 10 = -3344831479658869200, which is
valid for 64 bit longs, and evidently divisible by 10.

Also safely check that adding the digit won't cause an overflow too.

No testcase provided since one of the previous testcases flagged this issue up.

 * d-demangle.c: Include  if available.
 (LONG_MAX): Define if necessary.
 (dlang_number): Fix overflow.

From 6dc14e124c4a48928046403faca37504229b13c4 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:57:08 +
Subject: [PATCH 10/10] libiberty: Correct an invalid assumption.

As a counter example: 888 * 10 = -3344831479658869200, which is
valid for 64 bit longs, and evidently divisible by 10.

Also safely check that adding the digit won't cause an overflow too.

No testcase provided since one of the previous testcases flagged this issue up.

* d-demangle.c: Include  if available.
(LONG_MAX): Define if necessary.
(dlang_number): Fix overflow.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index becc402..4ffcdd1 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -42,6 +42,13 @@ If not, see .  */
 #include 
 #endif
 
+#ifdef HAVE_LIMITS_H
+#include 
+#endif
+#ifndef LONG_MAX
+# define LONG_MAX  (long)(((unsigned long) ~0) >> 1)
+#endif
+
 #include 
 #include "libiberty.h"
 
@@ -206,15 +213,18 @@ dlang_number (const char *mangled, long *ret)
 
   while (ISDIGIT (*mangled))
 {
+  long digit = mangled[0] - '0';
+  mangled++;
+
+  if (*ret > LONG_MAX / 10)
+	return NULL;
+
   (*ret) *= 10;
 
-  /* If an overflow occured when multiplying by ten, the result
-	 will not be a multiple of ten.  */
-  if ((*ret % 10) != 0)
+  if (LONG_MAX - digit < *ret)
 	return NULL;
 
-  (*ret) += mangled[0] - '0';
-  mangled++;
+  (*ret) += digit;
 }
 
   if (*mangled == '\0' || *ret < 0)
-- 
2.20.1



[PATCH 09/10] libiberty: Correctly handle error result in dlang_parse_assocarray()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

 * d-demangle.c (dlang_parse_assocarray): Correctly handle error result.
 * testsuite/d-demangle-expected: Add testcase.

From f3dd4107d4bd59b7f3370b17b25c9fd35d499ea3 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:46:30 +
Subject: [PATCH 09/10] libiberty: Correctly handle error result in
 dlang_parse_assocarray().

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

* d-demangle.c (dlang_parse_assocarray): Correctly handle error result.
* testsuite/d-demangle-expected: Add testcase.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index e98118e..becc402 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -1217,8 +1217,13 @@ dlang_parse_assocarray (string *decl, const char *mangled)
   while (elements--)
 {
   mangled = dlang_value (decl, mangled, NULL, '\0');
+  if (mangled == NULL)
+	return NULL;
+
   string_append (decl, ":");
   mangled = dlang_value (decl, mangled, NULL, '\0');
+  if (mangled == NULL)
+	return NULL;
 
   if (elements != 0)
 	string_append (decl, ", ");
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 44a8d3b..490d4e1 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -1322,3 +1322,7 @@ _D7__T2fnVlS8S5888S6S5
 --format=dlang
 _D1_B6961*
 _D1_B6961*
+# Could crash
+--format=dlang
+_D5__T1fVHacA66_
+_D5__T1fVHacA66_
-- 
2.20.1



[PATCH 07/10] libiberty: Correctly handle error result in dlang_parse_structlit()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

 * d-demangle.c (dlang_parse_structlit): Correctly handle error result.
 * testsuite/d-demangle-expected: Add testcase.

From 4911e6f481472b732277cc9b2136b0846474bb4a Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:37:41 +
Subject: [PATCH 07/10] libiberty: Correctly handle error result in
 dlang_parse_structlit().

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

* d-demangle.c (dlang_parse_structlit): Correctly handle error result.
* testsuite/d-demangle-expected: Add testcase.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index 303d2ee..5590417 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -1246,6 +1246,9 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
   while (args--)
 {
   mangled = dlang_value (decl, mangled, NULL, '\0');
+  if (mangled == NULL)
+	return NULL;
+
   if (args != 0)
 	string_append (decl, ", ");
 }
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 19665f5..0a5f9da 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -1314,3 +1314,7 @@ _D8__T2fnVa8_
 --format=dlang
 _D5__T2fnVmA1A1A9D
 _D5__T2fnVmA1A1A9D
+# Could crash
+--format=dlang
+_D7__T2fnVlS8S5888S6S5
+_D7__T2fnVlS8S5888S6S5
-- 
2.20.1



[PATCH 08/10] libiberty: Correctly handle error result in dlang_parse_tuple()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

 * d-demangle.c (dlang_parse_tuple): Correctly handle error result.
 * testsuite/d-demangle-expected: Add testcase.

From 7491ea105fd8d1d7887884594d30486ecf2cac08 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:40:48 +
Subject: [PATCH 08/10] libiberty: Correctly handle error result in
 dlang_parse_tuple().

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

* d-demangle.c (dlang_parse_tuple): Correctly handle error result.
* testsuite/d-demangle-expected: Add testcase.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index 5590417..e98118e 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -1503,6 +1503,9 @@ dlang_parse_tuple (string *decl, const char *mangled)
   while (elements--)
 {
   mangled = dlang_type (decl, mangled);
+  if (mangled == NULL)
+	return NULL;
+
   if (elements != 0)
 	string_append (decl, ", ");
 }
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 0a5f9da..44a8d3b 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -1318,3 +1318,7 @@ _D5__T2fnVmA1A1A9D
 --format=dlang
 _D7__T2fnVlS8S5888S6S5
 _D7__T2fnVlS8S5888S6S5
+# Could crash
+--format=dlang
+_D1_B6961*
+_D1_B6961*
-- 
2.20.1



[PATCH 05/10] libiberty: Fix stack underflow in dlang_parse_integer()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

A char array of size 10 was created on the stack to hold the decimal
representation of a long, which on my platform is 64 bits and hence has a
maximum value of 9223372036854775807, far exceeding 10 characters.

Fix this by bumping the size of the array to 20 characters.

 * d-demangle.c (dlang_parse_integer): Fix stack underflow.
 * testsuite/d-demangle-expected: Add testcase.

From 56a6202c87543dbf0a15d99e4dcb01507bf70f57 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:24:19 +
Subject: [PATCH 05/10] libiberty: Fix stack underflow in
 dlang_parse_integer().

A char array of size 10 was created on the stack to hold the decimal
representation of a long, which on my platform is 64 bits and hence has a
maximum value of 9223372036854775807, far exceeding 10 characters.

Fix this by bumping the size of the array to 20 characters.

* d-demangle.c (dlang_parse_integer): Fix stack underflow.
* testsuite/d-demangle-expected: Add testcase.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index 8acbf04..114d9e0 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -939,8 +939,8 @@ dlang_parse_integer (string *decl, const char *mangled, char type)
   if (type == 'a' || type == 'u' || type == 'w')
 {
   /* Parse character value.  */
-  char value[10];
-  int pos = 10;
+  char value[20];
+  int pos = sizeof(value);
   int width = 0;
   long val;
 
@@ -991,7 +991,7 @@ dlang_parse_integer (string *decl, const char *mangled, char type)
 	  for (; width > 0; width--)
 	value[--pos] = '0';
 
-	  string_appendn (decl, &(value[pos]), 10 - pos);
+	  string_appendn (decl, &(value[pos]), sizeof(value) - pos);
 	}
   string_append (decl, "'");
 }
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 547a2dd..9988238 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -1306,3 +1306,7 @@ rt.lifetime._d_newarrayOpT!(_d_newarrayiT)._d_newarrayOpT(const(TypeInfo), ulong
 --format=dlang
 _D4core8demangle16__T6mangleTFZPvZ6mangleFNaNbNfAxaAaZ11DotSplitter5emptyMxFNaNbNdNiNfZb
 core.demangle.mangle!(void*() function).mangle(const(char)[], char[]).DotSplitter.empty() const
+# Could crash
+--format=dlang
+_D8__T2fnVa8_
+_D8__T2fnVa8_
-- 
2.20.1



[PATCH 06/10] libiberty: Correctly handle error result in dlang_parse_arrayliteral()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

 * d-demangle.c (dlang_parse_arrayliteral): Correctly handle error result.
 * testsuite/d-demangle-expected: Add testcase.

From 8eca61f41b70891f4e2c456c4a12c06d3b4f3a3f Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:33:27 +
Subject: [PATCH 06/10] libiberty: Correctly handle error result in
 dlang_parse_arrayliteral().

The number of elements were being taken as valid and for each one a separator
was appended to the output, resulting in a huge memory bloat before crashing
later on due to a signed integer overflow.

* d-demangle.c (dlang_parse_arrayliteral): Correctly handle error result.
* testsuite/d-demangle-expected: Add testcase.

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index 114d9e0..303d2ee 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -1191,6 +1191,9 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
   while (elements--)
 {
   mangled = dlang_value (decl, mangled, NULL, '\0');
+  if (mangled == NULL)
+	return NULL;
+
   if (elements != 0)
 	string_append (decl, ", ");
 }
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 9988238..19665f5 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -1310,3 +1310,7 @@ core.demangle.mangle!(void*() function).mangle(const(char)[], char[]).DotSplitte
 --format=dlang
 _D8__T2fnVa8_
 _D8__T2fnVa8_
+# Could crash
+--format=dlang
+_D5__T2fnVmA1A1A9D
+_D5__T2fnVmA1A1A9D
-- 
2.20.1



[PATCH 04/10] libiberty: Fix crash in ada_demangle()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

The output buffer is pre-allocated to a maximum size under the assumption that
special names can only occur once, however nothing was enforcing this for
stream attributes.

To fix this we treat stream attributes that appear before the end of the
mangled input as an error.

 * cplus-dem.c (ada_demangle): Only accept stream attributes if they're at
 the end of the input.
 * testsuite/demangle-expected: Add testcase.

From c8dd053c841e9b04583ad6c6bf4550d30aa47990 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:18:14 +
Subject: [PATCH 04/10] libiberty: Fix crash in ada_demangle().

The output buffer is pre-allocated to a maximum size under the assumption that
special names can only occur once, however nothing was enforcing this for
stream attributes.

To fix this we treat stream attributes that appear before the end of the
mangled input as an error.

* cplus-dem.c (ada_demangle): Only accept stream attributes if they're at
the end of the input.
* testsuite/demangle-expected: Add testcase.

diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index afceed2..245cf11 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -254,6 +254,8 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
   p = mangled;
   while (1)
 {
+  int stream = 0;
+
   /* An entity names is expected.  */
   if (ISLOWER (*p))
 {
@@ -363,6 +365,7 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
   goto unknown;
 }
   p += 2;
+  stream = 1;
   strcpy (d, name);
   d += strlen (name);
 }
@@ -437,6 +440,10 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
   else
 goto unknown;
 }
+  else if (stream)
+{
+  goto unknown;
+}
   else
 {
   *d++ = '.';
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index f21ed00..8b830b6 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -81,6 +81,10 @@ _ZZaSFvOEES_
 
 _ZZeqFvOEES_z
 _ZZeqFvOEES_z
+# Could crash
+--format=gnat
+lSO__lSO
+
 #
 # demangler/80513 Test for bogus characters after __thunk_
 
-- 
2.20.1



[PATCH 03/10] libiberty: Fix a crash in d_print_comp_inner()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

'typed_name' is checked before the loop, but not checked after every
iteration. This can cause a crash if the input buffer is malformed since
'typed_name' can be assigned NULL.

To fix this, break out of the loop if we see it's NULL and handle that case
afterwards.

 * cp-demangle (d_print_comp_inner): Guard against a NULL 'typed_name'.
 * testsuite/demangle-expected: Add testcase.

From 3b36d9788fb9fe08ed9c83a57fb18bbfdc903543 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:13:26 +
Subject: [PATCH 03/10] libiberty: Fix a crash in d_print_comp_inner().

'typed_name' is checked before the loop, but not checked after every
iteration. This can cause a crash if the input buffer is malformed since
'typed_name' can be assigned NULL.

To fix this, break out of the loop if we see it's NULL and handle that case
afterwards.

* cp-demangle (d_print_comp_inner): Guard against a NULL 'typed_name'.
* testsuite/demangle-expected: Add testcase.

diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 02b5f9e..8ab0cd5 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -4757,12 +4757,8 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 	typed_name = d_right (typed_name);
 	if (typed_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
 	  typed_name = typed_name->u.s_unary_num.sub;
-	if (typed_name == NULL)
-	  {
-		d_print_error (dpi);
-		return;
-	  }
-	while (is_fnqual_component_type (typed_name->type))
+	while (typed_name != NULL
+		   && is_fnqual_component_type (typed_name->type))
 	  {
 		if (i >= sizeof adpm / sizeof adpm[0])
 		  {
@@ -4781,6 +4777,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 
 		typed_name = d_left (typed_name);
 	  }
+	if (typed_name == NULL)
+	  {
+		d_print_error (dpi);
+		return;
+	  }
 	  }
 
 	/* If typed_name is a template, then it applies to the
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index eb5264d..f21ed00 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -77,6 +77,10 @@ _ZmmAtl
 _ZZaSFvOEES_
 _ZZaSFvOEES_
 _ZZaSFvOEES_
+# Could crash
+
+_ZZeqFvOEES_z
+_ZZeqFvOEES_z
 #
 # demangler/80513 Test for bogus characters after __thunk_
 
-- 
2.20.1



[PATCH 01/10] libiberty: Fix an out of bounds read in d_expression_1()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

Passing "_ZmmAtl" to cplus_demangle() causes it to read past the end of the
input buffer. This is because cplus_demangle_type() may advance the current
offset so when control returns to d_expression_1() the current char may now
be the last valid byte and hence we cannot peek at the next char.

Fixed this by checking that the current char is still valid before checking
that the next char is too.

 * cp-demangle.c (d_expression_1): Don't peek ahead unless the current
 char is valid.
 * testsuite/demangle-expected: Add testcase.

From dadc7d7812e0c42c4a7c8c1f0525c4a11e0bd229 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 21:50:59 +
Subject: [PATCH 01/10] libiberty: Fix an out of bounds read in
 d_expression_1().

Passing "_ZmmAtl" to cplus_demangle() causes it to read past the end of the
input buffer. This is because cplus_demangle_type() may advance the current
offset so when control returns to d_expression_1() the current char may now
be the last valid byte and hence we cannot peek at the next char.

Fixed this by checking that the current char is still valid before checking
that the next char is too.

* cp-demangle.c (d_expression_1): Don't peek ahead unless the current
char is valid.
* testsuite/demangle-expected: Add testcase.

diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 4624cd5..8f6 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -3353,7 +3353,7 @@ d_expression_1 (struct d_info *di)
   d_advance (di, 2);
   if (peek == 't')
 	type = cplus_demangle_type (di);
-  if (!d_peek_next_char (di))
+  if (!d_peek_char (di) || !d_peek_next_char (di))
 	return NULL;
   return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
 			  type, d_exprlist (di, 'E'));
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 3723b7a..328d51a 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -68,6 +68,10 @@ _$_H1R
 
 _Q8ccQ4M2e.
 _Q8ccQ4M2e.
+# Could crash
+
+_ZmmAtl
+_ZmmAtl
 #
 # demangler/80513 Test for bogus characters after __thunk_
 
-- 
2.20.1



[PATCH 02/10] libiberty: Fix a crash in d_encoding()

2019-01-10 Thread Ben L
Hi all,

First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
there's obvious errors repeated in my patches. AFAICT I should be sending each
change individually rather than as one bulk patch, so I'm sorry about the spam
too.

All of these changes were found by fuzzing libiberty's demanglers over the
past week, and I have at least one more that it's currently crashing out on
but I haven't had time to look into why yet.

Obviously since this is my first time emailing I don't have write access to
commit any of these, so if any are approved then I'd be grateful if you can
commit them too.

Thanks,
Ben

--

Passing "_ZZaSFvOEES_" to cplus_demangle() without the DMGL_PARAMS flag causes
a crash due to d_right (dc) returning NULL inside d_encoding().

Check for this case and handle it as an error rather than crashing when trying
to dereference the right side's type.

 * cp-demangle.c (d_encoding): Guard against NULL return values from
 d_right (dc).
 * testsuite/demangle-expected: Add testcase.

From 5102da933a72628e34b68402168e571b09c54581 Mon Sep 17 00:00:00 2001
From: bobsayshilol 
Date: Wed, 9 Jan 2019 22:05:16 +
Subject: [PATCH 02/10] libiberty: Fix a crash in d_encoding().

Passing "_ZZaSFvOEES_" to cplus_demangle() without the DMGL_PARAMS flag causes
a crash due to d_right (dc) returning NULL inside d_encoding().

Check for this case and handle it as an error rather than crashing when trying
to dereference the right side's type.

* cp-demangle.c (d_encoding): Guard against NULL return values from
d_right (dc).
* testsuite/demangle-expected: Add testcase.

diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 8f6..02b5f9e 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -1330,8 +1330,14 @@ d_encoding (struct d_info *di, int top_level)
 	 really apply here; this happens when parsing a class
 	 which is local to a function.  */
 	  if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
-	while (is_fnqual_component_type (d_right (dc)->type))
-	  d_right (dc) = d_left (d_right (dc));
+	{
+	  while (d_right (dc) != NULL
+		 && is_fnqual_component_type (d_right (dc)->type))
+		d_right (dc) = d_left (d_right (dc));
+
+	  if (d_right (dc) == NULL)
+		dc = NULL;
+	}
 	}
   else
 	{
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 328d51a..eb5264d 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -72,6 +72,11 @@ _Q8ccQ4M2e.
 
 _ZmmAtl
 _ZmmAtl
+# Could crash
+--no-params
+_ZZaSFvOEES_
+_ZZaSFvOEES_
+_ZZaSFvOEES_
 #
 # demangler/80513 Test for bogus characters after __thunk_
 
-- 
2.20.1