From: Alan Modra Date: Sun, 15 Mar 2020 22:24:16 +0000 (+1030) Subject: ubsan: shift exponent 70 is too large X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=60e63c3e9750b036d50e58bc173591fa450601b6;p=deliverable%2Fbinutils-gdb.git ubsan: shift exponent 70 is too large * unwind-ia64.c (unw_decode_uleb128): Prevent overlarge shifts. Detect shift overflows and check that terminating byte is found. Print an error on a bad uleb128. --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 5f8af94680..ee1534f98a 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2020-03-16 Alan Modra + + * unwind-ia64.c (unw_decode_uleb128): Prevent overlarge shifts. + Detect shift overflows and check that terminating byte is found. + Print an error on a bad uleb128. + 2020-03-14 Alan Modra * readelf.c (process_file): Clean ba_cache. diff --git a/binutils/unwind-ia64.c b/binutils/unwind-ia64.c index b59a531e68..b9eae5bb21 100644 --- a/binutils/unwind-ia64.c +++ b/binutils/unwind-ia64.c @@ -544,21 +544,34 @@ static unw_word unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end) { unsigned shift = 0; + int status = 1; unw_word byte, result = 0; const unsigned char *bp = *dpp; while (bp < end) { byte = *bp++; - result |= (byte & 0x7f) << shift; + if (shift < sizeof (result) * 8) + { + result |= (byte & 0x7f) << shift; + if ((result >> shift) != (byte & 0x7f)) + /* Overflow. */ + status |= 2; + shift += 7; + } + else if ((byte & 0x7f) != 0) + status |= 2; if ((byte & 0x80) == 0) - break; - - shift += 7; + { + status &= ~1; + break; + } } *dpp = bp; + if (status != 0) + printf (_("Bad uleb128\n")); return result; }