]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf, libdw: Handle too many directories or files in the line table better.
authorMark Wielaard <mark@klomp.org>
Fri, 8 Jun 2018 12:04:40 +0000 (14:04 +0200)
committerMark Wielaard <mark@klomp.org>
Sun, 10 Jun 2018 15:02:22 +0000 (17:02 +0200)
The afl fuzzer found that the way we handle "too many" directories or files
in the (DWARF5 style) line table badly. In the case of eu-readelf we would
print an endless stream of "bad directory" or "bad file". Just stop printing
when the end of data is reached. In the case of dwarf_getsrclines we would
allocate a giant amount of memory, even if there was no data to actually
read in. Sanity check that the directory and file counts seem reasonable
compared to the amount of data left (assume we need at least 1 byte of
data per form describing the dirs or files).

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

index 79fcf1eacf6225d721e17cb1845140c12bca6e1d..ddd829661b8b42726c4194280c6046af81340709 100644 (file)
@@ -1,3 +1,7 @@
+2018-06-08  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_getsrclines.c (read_srclines): Sanity check ndirs and nfiles.
+
 2018-06-08  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_getlocation_attr.c (addr_valp): Set error and return NULL
index 07baebccc28106765fb33aec63a4b55ea1eb5c75..bb512ec67aead10f4b56a95a31d1a6abf8e2d9cd 100644 (file)
@@ -356,6 +356,11 @@ read_srclines (Dwarf *dbg,
 
       if (nforms == 0 && ndirs != 0)
        goto invalid_data;
+
+      /* Assume there is at least 1 byte needed per form to describe
+        the directory.  Filters out insanely large ndirs.  */
+      if (nforms != 0 && ndirs > (size_t) (lineendp - linep) / nforms)
+       goto invalid_data;
     }
 
   /* Arrange the list in array form.  */
@@ -561,6 +566,11 @@ read_srclines (Dwarf *dbg,
       if (nforms == 0 && nfiles != 0)
        goto invalid_data;
 
+      /* Assume there is at least 1 byte needed per form to describe
+        the file.  Filters out insanely large nfiles.  */
+      if (nforms != 0 && nfiles > (size_t) (lineendp - linep) / nforms)
+       goto invalid_data;
+
       Dwarf_Attribute attr;
       attr.cu = &fake_cu;
       for (unsigned int n = 0; n < nfiles; n++)
index 778238e20b7a5ad52a88ae9aa1bde4d5588e3899..ca1917a23502d7aef95fde00f171ebf070a3780d 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-08  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (print_debug_line_section): Stop printing directories
+       and files when we are at the end of the unit data.
+
 2018-06-07  Mark Wielaard  <mark@klomp.org>
 
        * readelf.c (format_result): Removed.
index f9514a1d53daa09bc84e6dfba10f036d3dcfc411..af78f17e2121fd54c6b659d99923409dffe6ec82 100644 (file)
@@ -8294,6 +8294,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
                    printf (", ");
                }
              printf ("\n");
+             if (linep >= lineendp)
+               goto invalid_unit;
            }
        }
       else
@@ -8370,6 +8372,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
                    printf (", ");
                }
              printf ("\n");
+             if (linep >= lineendp)
+               goto invalid_unit;
            }
        }
       else