This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libbacktrace patch committed: Fix leb128 overflow test
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Philip Prindeville <philipp at fedoraproject dot org>
- Date: Wed, 03 Oct 2012 15:07:15 -0700
- Subject: libbacktrace patch committed: Fix leb128 overflow test
This patch to libbacktrace fixes the overflow test for the leb128
reading routines. What matters is not the shift after the loop, but the
shift within the loop. This also removes the setting of unit_buf.start
in build_address_map, which was simply wrong and was causing the error
message to print the wrong offset in the .debug_info section.
Bootstrapped and ran libbacktrace testsuite on
x86_64-unknown-linux-gnu. Committed to mainline.
Ian
2012-10-03 Ian Lance Taylor <iant@google.com>
* dwarf.c (read_uleb128): Fix overflow test.
(read_sleb128): Likewise.
(build_address_map): Don't change unit_buf.start.
Index: dwarf.c
===================================================================
--- dwarf.c (revision 191858)
+++ dwarf.c (working copy)
@@ -524,10 +524,12 @@ read_uleb128 (struct dwarf_buf *buf)
{
uint64_t ret;
unsigned int shift;
+ int overflow;
unsigned char b;
ret = 0;
shift = 0;
+ overflow = 0;
do
{
const unsigned char *p;
@@ -536,14 +538,17 @@ read_uleb128 (struct dwarf_buf *buf)
if (!advance (buf, 1))
return 0;
b = *p;
- ret |= ((uint64_t) (b & 0x7f)) << shift;
+ if (shift < 64)
+ ret |= ((uint64_t) (b & 0x7f)) << shift;
+ else if (!overflow)
+ {
+ dwarf_buf_error (buf, "LEB128 overflows uint64_t");
+ overflow = 1;
+ }
shift += 7;
}
while ((b & 0x80) != 0);
- if (shift > 64)
- dwarf_buf_error (buf, "LEB128 overflows uint64_5");
-
return ret;
}
@@ -554,10 +559,12 @@ read_sleb128 (struct dwarf_buf *buf)
{
uint64_t val;
unsigned int shift;
+ int overflow;
unsigned char b;
val = 0;
shift = 0;
+ overflow = 0;
do
{
const unsigned char *p;
@@ -566,15 +573,18 @@ read_sleb128 (struct dwarf_buf *buf)
if (!advance (buf, 1))
return 0;
b = *p;
- val |= ((uint64_t) (b & 0x7f)) << shift;
+ if (shift < 64)
+ val |= ((uint64_t) (b & 0x7f)) << shift;
+ else if (!overflow)
+ {
+ dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
+ overflow = 1;
+ }
shift += 7;
}
while ((b & 0x80) != 0);
- if (shift > 64)
- dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
-
- if ((b & 0x40) != 0)
+ if ((b & 0x40) != 0 && shift < 64)
val |= ((uint64_t) -1) << shift;
return (int64_t) val;
@@ -1262,7 +1272,6 @@ build_address_map (struct backtrace_stat
}
unit_buf = info;
- unit_buf.start = info.buf;
unit_buf.left = len;
if (!advance (&info, len))