aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-03-16 08:54:16 +1030
committerAlan Modra <amodra@gmail.com>2020-03-16 13:04:49 +1030
commit60e63c3e9750b036d50e58bc173591fa450601b6 (patch)
tree165272afbf8a2d53cffc45816cbf0644595b18d8
parent7bac4137d757be98de8f6f8d8a649f04cacfdd2f (diff)
downloadgdb-60e63c3e9750b036d50e58bc173591fa450601b6.zip
gdb-60e63c3e9750b036d50e58bc173591fa450601b6.tar.gz
gdb-60e63c3e9750b036d50e58bc173591fa450601b6.tar.bz2
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.
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/unwind-ia64.c21
2 files changed, 23 insertions, 4 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 5f8af94..ee1534f 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2020-03-16 Alan Modra <amodra@gmail.com>
+
+ * 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 <amodra@gmail.com>
* readelf.c (process_file): Clean ba_cache.
diff --git a/binutils/unwind-ia64.c b/binutils/unwind-ia64.c
index b59a531..b9eae5b 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;
}