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

Message ID CY4PR22MB0102F161D466238C087DE367E7850@CY4PR22MB0102.namprd22.prod.outlook.com
State New
Headers show
Series
  • [01/10] libiberty: Fix an out of bounds read in d_expression_1()
Related show

Commit Message

Ben L Jan. 11, 2019, 12:13 a.m.
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.

Comments

Jeff Law April 29, 2019, 10:19 p.m. | #1
On 1/10/19 5:13 PM, Ben L wrote:
> 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.

> 

Thanks.  I've committed this to the GCC trunk.

jeff

Patch

From dadc7d7812e0c42c4a7c8c1f0525c4a11e0bd229 Mon Sep 17 00:00:00 2001
From: bobsayshilol <bobsayshilol@live.co.uk>
Date: Wed, 9 Jan 2019 21:50:59 +0000
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..dddd8f6 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