]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Add bounds checking to dwarf_getpubnames.
authorMark Wielaard <mjw@redhat.com>
Mon, 15 Dec 2014 13:56:07 +0000 (14:56 +0100)
committerMark Wielaard <mjw@redhat.com>
Wed, 17 Dec 2014 15:43:28 +0000 (16:43 +0100)
Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdw/ChangeLog
libdw/dwarf_getpubnames.c

index b1fb582b39d93e28d8576024b650a0782ad8d989..068d452123442a1035838b0c44e938fd5dd79e4c 100644 (file)
@@ -1,3 +1,10 @@
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf_getpubnames.c (get_offsets): Make sure whole unit fall inside
+       section data.
+       (dwarf_getpubnames): Make sure section data contains string zero
+       terminator.
+
 2014-12-16  Mark Wielaard  <mjw@redhat.com>
 
        * memory-access.h (__libdw_get_sleb128): Unroll the first step to help
index 12728a34385921acf9e5bd95d7d928780ce64957..c8b9f9f6c0d3d53f5e0ecf8f948210f6d5a6754c 100644 (file)
@@ -88,9 +88,11 @@ get_offsets (Dwarf *dbg)
       /* Now we know the offset of the first offset/name pair.  */
       mem[cnt].set_start = readp + 2 + 2 * len_bytes - startp;
       mem[cnt].address_len = len_bytes;
-      if (mem[cnt].set_start >= dbg->sectiondata[IDX_debug_pubnames]->d_size)
+      size_t max_size = dbg->sectiondata[IDX_debug_pubnames]->d_size;
+      if (mem[cnt].set_start >= max_size
+         || len - (2 + 2 * len_bytes) > max_size - mem[cnt].set_start)
        /* Something wrong, the first entry is beyond the end of
-          the section.  */
+          the section.  Or the length of the whole unit is too big.  */
        break;
 
       /* Read the version.  It better be two for now.  */
@@ -184,6 +186,8 @@ dwarf_getpubnames (dbg, callback, arg, offset)
 
   unsigned char *startp
     = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf;
+  unsigned char *endp
+    = startp + dbg->sectiondata[IDX_debug_pubnames]->d_size;
   unsigned char *readp = startp + offset;
   while (1)
     {
@@ -208,7 +212,13 @@ dwarf_getpubnames (dbg, callback, arg, offset)
          gl.die_offset += dbg->pubnames_sets[cnt].cu_offset;
 
          gl.name = (char *) readp;
-         readp = (unsigned char *) rawmemchr (gl.name, '\0') + 1;
+         readp = (unsigned char *) memchr (gl.name, '\0', endp - readp);
+         if (unlikely (readp == NULL))
+           {
+             __libdw_seterrno (DWARF_E_INVALID_DWARF);
+             return -1l;
+           }
+         readp++;
 
          /* We found name and DIE offset.  Report it.  */
          if (callback (dbg, &gl, arg) != DWARF_CB_OK)