From: Mark Wielaard Date: Fri, 8 Jun 2018 21:30:37 +0000 (+0200) Subject: readelf: Calculate max_entries instead of needed bytes (and overflowing). X-Git-Tag: elfutils-0.172~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=305211458a58a99b999639171c55724e3d9b51c0;p=thirdparty%2Felfutils.git readelf: Calculate max_entries instead of needed bytes (and overflowing). The afl fuzzer found that we would overflow the needed bytes when calculating how many index entries would fit in the .debug_loclists and .debug_rnglists tables. To fix this just calculate the max number of entries. If the offset entry count is larger than that, do emit an error, but print up to max_entries of offsets (so the user can more clearly see what is wrong with their table). Signed-off-by: Mark Wielaard --- diff --git a/src/ChangeLog b/src/ChangeLog index ca1917a23..8ebb5fb73 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2018-06-08 Mark Wielaard + + * readelf.c (print_debug_rnglists_section): Calculate max_entries + instead of needed bytes to prevent overflowing. Always print + max_entries (but not more). + (print_debug_loclists_section): Likewise. + 2018-06-08 Mark Wielaard * readelf.c (print_debug_line_section): Stop printing directories diff --git a/src/readelf.c b/src/readelf.c index af78f17e2..bbaaf96a8 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -5656,12 +5656,12 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod, const unsigned char *offset_array_start = readp; if (offset_entry_count > 0) { - uint64_t needed = offset_entry_count * offset_size; - if (unit_length - 8 < needed) + uint64_t max_entries = (unit_length - 8) / offset_size; + if (offset_entry_count > max_entries) { error (0, 0, gettext ("too many offset entries for unit length")); - goto next_table; + offset_entry_count = max_entries; } printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"), @@ -8864,12 +8864,12 @@ print_debug_loclists_section (Dwfl_Module *dwflmod, const unsigned char *offset_array_start = readp; if (offset_entry_count > 0) { - uint64_t needed = offset_entry_count * offset_size; - if (unit_length - 8 < needed) + uint64_t max_entries = (unit_length - 8) / offset_size; + if (offset_entry_count > max_entries) { error (0, 0, gettext ("too many offset entries for unit length")); - goto next_table; + offset_entry_count = max_entries; } printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),