]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Check there is enough space for CU 64bit length, version and type.
authorMark Wielaard <mark@klomp.org>
Fri, 1 Feb 2019 13:03:38 +0000 (14:03 +0100)
committerMark Wielaard <mark@klomp.org>
Fri, 1 Feb 2019 13:06:18 +0000 (14:06 +0100)
We only checked we could read the initial length and after knowing the
version and type whether the unit header was the right size. Also check
there are at least enough bytes to read the 64bit length, version and
unit type bytes.

https://sourceware.org/bugzilla/show_bug.cgi?id=24140

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf_nextcu.c

index ff3880df12f5e5a09c4dbcb8618ecae788c7c6b7..aaa629601bf79802db39c779a64e108efad38717 100644 (file)
@@ -1,3 +1,9 @@
+2019-02-02  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_nextcu.c (__libdw_next_unit): Define bytes_end.
+       Check there are enough bytes to read extended lenght, version
+       and unit.
+
 2019-01-20  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_getsrclines.c (read_srclines): Check terminating NUL byte
index be1132707d0cd79260cc6aee3f492d9be9520f92..67cec4497949e38bb6013dacdb9fece6e8476a3c 100644 (file)
@@ -85,6 +85,7 @@ __libdw_next_unit (Dwarf *dwarf, bool v4_debug_types, Dwarf_Off off,
      beginning of the CU entry.  */
   const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
   const unsigned char *bytes = data + off;
+  const unsigned char *bytes_end = data + dwarf->sectiondata[sec_idx]->d_size;
 
   /* The format of the CU header is described in dwarf2p1 7.5.1 and
      changed in DWARFv5 (to include unit type, switch location of some
@@ -164,17 +165,27 @@ __libdw_next_unit (Dwarf *dwarf, bool v4_debug_types, Dwarf_Off off,
     }
 
   if (length == DWARF3_LENGTH_64_BIT)
-    /* This is a 64-bit DWARF format.  */
-    length = read_8ubyte_unaligned_inc (dwarf, bytes);
+    {
+      /* This is a 64-bit DWARF format.  */
+      if (bytes_end - bytes < 8)
+       goto invalid;
+      length = read_8ubyte_unaligned_inc (dwarf, bytes);
+    }
 
   /* Read the version stamp.  Always a 16-bit value.  */
+  if (bytes_end - bytes < 2)
+    goto invalid;
   uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes);
 
   /* We keep unit_type at zero for older DWARF since we cannot
      easily guess whether it is a compile or partial unit.  */
   uint8_t unit_type = 0;
   if (version >= 5)
-    unit_type = *bytes++;
+    {
+      if (bytes_end - bytes < 1)
+       goto invalid;
+      unit_type = *bytes++;
+    }
 
   /* All these are optional.  */
   Dwarf_Off subdie_off = 0;