]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: dwarf_getaranges check there is enough data before reading.
authorMark Wielaard <mjw@redhat.com>
Tue, 5 May 2015 08:16:42 +0000 (10:16 +0200)
committerMark Wielaard <mjw@redhat.com>
Tue, 12 May 2015 14:40:00 +0000 (16:40 +0200)
https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c30

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdw/ChangeLog
libdw/dwarf_getaranges.c

index fd3e4adfbe737efb1136c5289966c991c0d3e3d1..f5dfc8f77856b9398b8a670960ab40c66fe960a7 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-05  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf_getaranges.c (dwarf_getaranges): Check there is enough data
+       left before reading values.
+
 2015-05-04  Anthony G. Basile  <blueness@gentoo.org>
 
        * Makefile.am (libdw_so_SOURCES): Append $(argp_LDADD) to link
index 4953af53cb25767fee50324fac2c19f6d08e06de..6c6169e957bfb0aedd0498bb07175a3539296ed6 100644 (file)
@@ -110,10 +110,16 @@ dwarf_getaranges (dbg, aranges, naranges)
 
         5. A 1-byte unsigned integer containing the size in bytes of
         a segment descriptor on the target system.  */
+      if (unlikely (readp + 4 > readendp))
+       goto invalid;
+
       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
       unsigned int length_bytes = 4;
       if (length == DWARF3_LENGTH_64_BIT)
        {
+         if (unlikely (readp + 8 > readendp))
+           goto invalid;
+
          length = read_8ubyte_unaligned_inc (dbg, readp);
          length_bytes = 8;
        }
@@ -121,6 +127,9 @@ dwarf_getaranges (dbg, aranges, naranges)
                         && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
        goto invalid;
 
+      if (unlikely (readp + 2 > readendp))
+       goto invalid;
+
       unsigned int version = read_2ubyte_unaligned_inc (dbg, readp);
       if (version != 2)
        {
@@ -136,14 +145,14 @@ dwarf_getaranges (dbg, aranges, naranges)
          return -1;
        }
 
-      Dwarf_Word offset;
+      Dwarf_Word offset = 0;
       if (__libdw_read_offset_inc (dbg,
                                   IDX_debug_aranges, &readp,
                                   length_bytes, &offset, IDX_debug_info, 4))
        goto fail;
 
       unsigned int address_size = *readp++;
-      if (address_size != 4 && address_size != 8)
+      if (unlikely (address_size != 4 && address_size != 8))
        goto invalid;
 
       /* We don't actually support segment selectors.  */
@@ -164,6 +173,9 @@ dwarf_getaranges (dbg, aranges, naranges)
                                        address_size, &range_address))
            goto fail;
 
+         if (readp + address_size > readendp)
+           goto invalid;
+
          if (address_size == 4)
            range_length = read_4ubyte_unaligned_inc (dbg, readp);
          else