From 834f871cdc6e5d9f5bda9ce607fd3c47f41a2ade Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 10 Feb 2015 17:53:53 +0000 Subject: [PATCH] Fix memory access violations discovered by running readelf compiled with undefined memory access sanitization on fuzzed binaries. PR binutils/17531 * dwarf.c (display_debug_pubnames_worker): Use dwarf_vma type for offset. * readelf.c (dump_relocations): Handle printing offsets which are MIN_INT. (process_corefile_note_segment): Add range check of the namesz field. --- binutils/ChangeLog | 8 ++++++++ binutils/dwarf.c | 6 +++--- binutils/readelf.c | 17 +++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 4befee323ac..a5b227e89e6 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -22,6 +22,14 @@ since correct initialisation cannot be relied upon. (process_cu_tu_index): Improve range checks. + PR binutils/17531 + * dwarf.c (display_debug_pubnames_worker): Use dwarf_vma type for + offset. + * readelf.c (dump_relocations): Handle printing offsets which are + MIN_INT. + (process_corefile_note_segment): Add range check of the namesz + field. + 2015-02-09 Mark Wielaard * dwarf.c (read_and_display_attr_value): Handle DW_LANG_Fortran03 diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 426dca58a5e..74a5e7afbb6 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -3725,7 +3725,7 @@ display_debug_pubnames_worker (struct dwarf_section *section, while (start < end) { unsigned char *data; - unsigned long offset; + dwarf_vma offset; unsigned int offset_size, initial_length_size; data = start; @@ -3824,11 +3824,11 @@ display_debug_pubnames_worker (struct dwarf_section *section, kind_name = get_gdb_index_symbol_kind_name (kind); is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (kind_data); printf (" %-6lx %s,%-10s %.*s\n", - offset, is_static ? _("s") : _("g"), + (unsigned long) offset, is_static ? _("s") : _("g"), kind_name, (int) maxprint, data); } else - printf (" %-6lx\t%.*s\n", offset, (int) maxprint, data); + printf (" %-6lx\t%.*s\n", (unsigned long) offset, (int) maxprint, data); data += strnlen ((char *) data, maxprint) + 1; if (data >= end) diff --git a/binutils/readelf.c b/binutils/readelf.c index 00bcb1d4bc2..bc7bd88ad74 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1611,7 +1611,10 @@ dump_relocations (FILE * file, { bfd_signed_vma off = rels[i].r_addend; - if (off < 0) + /* PR 17531: file: 2e63226f. */ + if (off == ((bfd_signed_vma) 1) << ((sizeof (bfd_signed_vma) * 8) - 1)) + printf (" + %" BFD_VMA_FMT "x", off); + else if (off < 0) printf (" - %" BFD_VMA_FMT "x", - off); else printf (" + %" BFD_VMA_FMT "x", off); @@ -1623,7 +1626,10 @@ dump_relocations (FILE * file, bfd_signed_vma off = rels[i].r_addend; printf ("%*c", is_32bit_elf ? 12 : 20, ' '); - if (off < 0) + /* PR 17531: file: 2e63226f. */ + if (off == ((bfd_signed_vma) 1) << ((sizeof (bfd_signed_vma) * 8) - 1)) + printf ("%" BFD_VMA_FMT "x", off); + else if (off < 0) printf ("-%" BFD_VMA_FMT "x", - off); else printf ("%" BFD_VMA_FMT "x", off); @@ -15065,6 +15071,13 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) inote.namedata = external->name; inote.descsz = BYTE_GET (external->descsz); inote.descdata = inote.namedata + align_power (inote.namesz, 2); + /* PR 17531: file: 3443835e. */ + if (inote.descdata < (char *) pnotes) + { + warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz); + inote.descdata = inote.namedata; + inote.namesz = 0; + } inote.descpos = offset + (inote.descdata - (char *) pnotes); next = inote.descdata + align_power (inote.descsz, 2); } -- 2.30.2