]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: Make sure print_form_data always consumes DW_FORM_strx[1234] data.
authorMark Wielaard <mark@klomp.org>
Tue, 12 Jun 2018 10:22:13 +0000 (12:22 +0200)
committerMark Wielaard <mark@klomp.org>
Sat, 16 Jun 2018 22:56:05 +0000 (00:56 +0200)
Found by afl-fuzz. When printing DW_FORM_strx[1234] data eu-readelf didn't
increase readp which meant eu-readelf would keep printing the same line
dirs or files encoded with strx[1234] names. This meant that for insane
large dir or file counts eu-readelf would just keep printing endlessly
because we never reached and of the .debug_line buffer.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/memory-access.h
src/ChangeLog
src/readelf.c

index 7832165407e59caf6fec6560334df1ad4b8054c7..6492c976b5e3b411a673212d3e141f37dfa6421c 100644 (file)
@@ -1,3 +1,7 @@
+2018-06-12  Mark Wielaard  <mark@klomp.org>
+
+       * memory-access.h (read_3ubyte_unaligned_inc): New define.
+
 2018-06-12  Mark Wielaard  <mark@klomp.org>
 
        * libdw.h (__libdw_dieabbrev): Set die->abbrev to DWARF_END_ABBREV
index 22918cb9497aa5b4061ae02c277b15dcf7fe9231..a39ad6d294804d2b99874a056d02de70a79103bc 100644 (file)
@@ -362,6 +362,11 @@ read_3ubyte_unaligned (Dwarf *dbg, const unsigned char *p)
 }
 
 
+#define read_3ubyte_unaligned_inc(Dbg, Addr) \
+  ({ uint32_t t_ = read_2ubyte_unaligned (Dbg, Addr);                        \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 3);                    \
+     t_; })
+
 #define read_addr_unaligned_inc(Nbytes, Dbg, Addr)                     \
   (assert ((Nbytes) == 4 || (Nbytes) == 8),                            \
     ((Nbytes) == 4 ? read_4ubyte_unaligned_inc (Dbg, Addr)             \
index 3d266e23db8c824ca4e8094db43a731fb62cabe9..d401da27dffc1c278d2db75b4cf512e20755cb6c 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-12  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (print_form_data): Don't increase strreadp after use.
+       Do increase readp for DW_FORM_strx[1234].
+
 2018-06-16  Mark Wielaard  <mark@klomp.org>
 
        * readelf.c (print_debug_loc_section): Make sure next_off doesn't
index 720d7f3fea1285e8d57166bd0df9353cb841d407..a6173806c74cd26613e46f78f583a534182c18a3 100644 (file)
@@ -8074,9 +8074,9 @@ print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
            {
              Dwarf_Off idx;
              if (offset_len == 8)
-               idx = read_8ubyte_unaligned_inc (dbg, strreadp);
+               idx = read_8ubyte_unaligned (dbg, strreadp);
              else
-               idx = read_4ubyte_unaligned_inc (dbg, strreadp);
+               idx = read_4ubyte_unaligned (dbg, strreadp);
 
              data = dbg->sectiondata[IDX_debug_str];
              if (data == NULL || idx >= data->d_size
@@ -8093,25 +8093,25 @@ print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
     case DW_FORM_strx1:
       if (readendp - readp < 1)
        goto invalid_data;
-      val = *readp;
+      val = *readp++;
       goto strx_val;
 
     case DW_FORM_strx2:
       if (readendp - readp < 2)
        goto invalid_data;
-      val = read_2ubyte_unaligned (dbg, readp);
+      val = read_2ubyte_unaligned_inc (dbg, readp);
       goto strx_val;
 
     case DW_FORM_strx3:
       if (readendp - readp < 3)
        goto invalid_data;
-      val = read_3ubyte_unaligned (dbg, readp);
+      val = read_3ubyte_unaligned_inc (dbg, readp);
       goto strx_val;
 
     case DW_FORM_strx4:
       if (readendp - readp < 4)
        goto invalid_data;
-      val = read_4ubyte_unaligned (dbg, readp);
+      val = read_4ubyte_unaligned_inc (dbg, readp);
       goto strx_val;
 
     default: