summaryrefslogtreecommitdiff
path: root/libbacktrace
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-03 22:07:12 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-03 22:07:12 +0000
commit68dd54731b19ab8bd26b091b2dd16c3fe9f40ef5 (patch)
tree0b7f834cad3ef78befbe7181d423d4ee7dde5768 /libbacktrace
parentddd51bb849c45ceae74e9f6985a85bc58c341e46 (diff)
downloadgcc-68dd54731b19ab8bd26b091b2dd16c3fe9f40ef5.tar.gz
* dwarf.c (read_uleb128): Fix overflow test.
(read_sleb128): Likewise. (build_address_map): Don't change unit_buf.start. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192053 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libbacktrace')
-rw-r--r--libbacktrace/ChangeLog6
-rw-r--r--libbacktrace/dwarf.c29
2 files changed, 25 insertions, 10 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index eca80147a1c..88a7eb0ba8e 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2012-10-02 Uros Bizjak <ubizjak@gmail.com>
PR other/54761
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 68ebb4e3ad1..25973cb7621 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -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_state *state,
}
unit_buf = info;
- unit_buf.start = info.buf;
unit_buf.left = len;
if (!advance (&info, len))