We could end up with a negative length in a call to memchr. https://sourceware.org/bugzilla/show_bug.cgi?id=23782
Signed-off-by: Mark Wielaard <m...@klomp.org> --- src/ChangeLog | 5 +++++ src/readelf.c | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 8fb3deb..1b29bb8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-10-16 Mark Wielaard <m...@klomp.org> + + * readelf.c (print_debug_frame_section): Make sure readp is never + greater than cieend. + 2018-10-14 Mark Wielaard <m...@klomp.org> * ar.c (do_oper_extract): Assume epoch if ar_date is bogus. diff --git a/src/readelf.c b/src/readelf.c index bddcd70..e55fece 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6598,18 +6598,24 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, ptrdiff_t start = readp - (unsigned char *) data->d_buf; const unsigned char *const cieend = readp + unit_length; - if (unlikely (cieend > dataend || readp + 8 > dataend)) + if (unlikely (cieend > dataend)) goto invalid_data; Dwarf_Off cie_id; if (length == 4) { + if (unlikely (cieend - readp < 4)) + goto invalid_data; cie_id = read_4ubyte_unaligned_inc (dbg, readp); if (!is_eh_frame && cie_id == DW_CIE_ID_32) cie_id = DW_CIE_ID_64; } else - cie_id = read_8ubyte_unaligned_inc (dbg, readp); + { + if (unlikely (cieend - readp < 8)) + goto invalid_data; + cie_id = read_8ubyte_unaligned_inc (dbg, readp); + } uint_fast8_t version = 2; unsigned int code_alignment_factor; @@ -6621,6 +6627,8 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64)) { + if (unlikely (cieend - readp < 2)) + goto invalid_data; version = *readp++; const char *const augmentation = (const char *) readp; readp = memchr (readp, '\0', cieend - readp); -- 1.8.3.1