aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2016-11-15 19:31:50 +0000
committerMark Wielaard <mark@klomp.org>2016-11-18 11:06:18 +0100
commit1706852c3c6c1d39f949c933d37647d02509b9cb (patch)
treec5b36324ccb38e94d7c63d06b677cf68ca562b1f /libiberty
parentlibiberty: Add -Wshadow=local to warning flags (if supported). (diff)
downloadbinutils-gdb-1706852c3c6c1d39f949c933d37647d02509b9cb.tar.gz
binutils-gdb-1706852c3c6c1d39f949c933d37647d02509b9cb.tar.bz2
binutils-gdb-1706852c3c6c1d39f949c933d37647d02509b9cb.zip
libiberty: Fix some demangler crashes caused by reading past end of input.
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.
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog11
-rw-r--r--libiberty/cplus-dem.c14
-rw-r--r--libiberty/testsuite/demangle-expected20
3 files changed, 41 insertions, 4 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index d0c5595fce6..ea12ba277a0 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,14 @@
+2016-11-14 Mark Wielaard <mark@klomp.org>
+
+ * 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.
+
2016-11-06 Mark Wielaard <mark@klomp.org>
* configure.ac (ac_libiberty_warn_cflags): Add -Wshadow=local.
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index c955bfbe1e7..3125a457b9d 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -1654,7 +1654,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 */
@@ -2133,6 +2136,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);
@@ -2977,7 +2982,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] == '_')
{
@@ -2991,7 +2996,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>"
@@ -3761,11 +3766,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 5badc3e5849..236161c2fe3 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.