From: Mark Wielaard Date: Fri, 8 Jun 2018 12:04:40 +0000 (+0200) Subject: readelf, libdw: Handle too many directories or files in the line table better. X-Git-Tag: elfutils-0.172~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e30fb282d32fe3e082f66c936db4b2988c290dc;p=thirdparty%2Felfutils.git readelf, libdw: Handle too many directories or files in the line table better. 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 --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 79fcf1eac..ddd829661 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2018-06-08 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Sanity check ndirs and nfiles. + 2018-06-08 Mark Wielaard * dwarf_getlocation_attr.c (addr_valp): Set error and return NULL diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 07baebccc..bb512ec67 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -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++) diff --git a/src/ChangeLog b/src/ChangeLog index 778238e20..ca1917a23 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-06-08 Mark Wielaard + + * 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 * readelf.c (format_result): Removed. diff --git a/src/readelf.c b/src/readelf.c index f9514a1d5..af78f17e2 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -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