This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]