public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libiberty: Fix some demangler crashes caused by reading past end of input.
@ 2016-11-14  9:20 Mark Wielaard
  2016-11-15 16:56 ` Ian Lance Taylor
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2016-11-14  9:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: Mark Wielaard

In various situations the cplus_demangle () function could read past the
end of input causing crashes. Add checks in various places to not advance
the demangle string location and fail early when end of string is reached.
Add various examples of input strings to the testsuite that would crash
test-demangle before the fixes.

Found by using the American Fuzzy Lop (afl) fuzzer.

libiberty/ChangeLog:

       * cplus-dem.c (demangle_signature): After 'H', template function,
       no success and don't advance position if end of string reached.
       (demangle_template): After 'z', template name, return zero on
       premature end of string.
       (gnu_special): Guard strchr against searching for zero characters.
       (do_type): If member, only advance mangled string when 'F' found.
       * testsuite/demangle-expected: Add examples of strings that could
       crash the demangler by reading past end of input.
---
 
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 8a699ee..0386da5 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -1697,7 +1697,10 @@ demangle_signature (struct work_stuff *work,
 					   0);
 	      if (!(work->constructor & 1))
 		expect_return_type = 1;
-	      (*mangled)++;
+	      if (!**mangled)
+		success = 0;
+	      else
+	        (*mangled)++;
 	      break;
 	    }
 	  /* fall through */
@@ -2176,6 +2179,8 @@ demangle_template (struct work_stuff *work, const char **mangled,
 	{
 	  int idx;
 	  (*mangled)++;
+	  if (**mangled == '\0')
+	    return (0);
 	  (*mangled)++;
 
 	  idx = consume_count_with_underscores (mangled);
@@ -3020,7 +3025,7 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
   int success = 1;
   const char *p;
 
-  if ((*mangled)[0] == '_'
+  if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
       && strchr (cplus_markers, (*mangled)[1]) != NULL
       && (*mangled)[2] == '_')
     {
@@ -3034,7 +3039,7 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
 		&& (*mangled)[3] == 't'
 		&& (*mangled)[4] == '_')
 	       || ((*mangled)[1] == 'v'
-		   && (*mangled)[2] == 't'
+		   && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
 		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
     {
       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
@@ -3804,11 +3809,12 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
 		    break;
 		  }
 
-		if (*(*mangled)++ != 'F')
+		if (*(*mangled) != 'F')
 		  {
 		    success = 0;
 		    break;
 		  }
+		(*mangled)++;
 	      }
 	    if ((member && !demangle_nested_args (work, mangled, &decl))
 		|| **mangled != '_')
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 5badc3e..236161c 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4606,3 +4606,23 @@ void f<void, int, false>(void (*)(int) noexcept)
 
 _Z1fIvJiELb0EEvPDwiEFT_DpT0_E
 void f<void, int, false>(void (*)(int) throw(int))
+
+# Could crash
+_
+_
+
+# Could crash
+_vt
+_vt
+
+# Could crash
+_$_1Acitz
+_$_1Acitz
+
+# Could crash
+_$_H1R
+_$_H1R
+
+# Could crash
+_Q8ccQ4M2e.
+_Q8ccQ4M2e.
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] libiberty: Fix some demangler crashes caused by reading past end of input.
  2016-11-14  9:20 [PATCH] libiberty: Fix some demangler crashes caused by reading past end of input Mark Wielaard
@ 2016-11-15 16:56 ` Ian Lance Taylor
  0 siblings, 0 replies; 2+ messages in thread
From: Ian Lance Taylor @ 2016-11-15 16:56 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: gcc-patches

On Mon, Nov 14, 2016 at 1:19 AM, Mark Wielaard <mark@klomp.org> wrote:
> In various situations the cplus_demangle () function could read past the
> end of input causing crashes. Add checks in various places to not advance
> the demangle string location and fail early when end of string is reached.
> Add various examples of input strings to the testsuite that would crash
> test-demangle before the fixes.
>
> Found by using the American Fuzzy Lop (afl) fuzzer.
>
> libiberty/ChangeLog:
>
>        * cplus-dem.c (demangle_signature): After 'H', template function,
>        no success and don't advance position if end of string reached.
>        (demangle_template): After 'z', template name, return zero on
>        premature end of string.
>        (gnu_special): Guard strchr against searching for zero characters.
>        (do_type): If member, only advance mangled string when 'F' found.
>        * testsuite/demangle-expected: Add examples of strings that could
>        crash the demangler by reading past end of input.
> ---

This is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-11-15 16:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-14  9:20 [PATCH] libiberty: Fix some demangler crashes caused by reading past end of input Mark Wielaard
2016-11-15 16:56 ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).