From e6d042fe27102cb789407ccb2ec1663aa9c65129 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 14 Sep 2016 15:32:01 +0100 Subject: Fix seg-fault in objdump when run on a fuzzed PE binary. PR binutils/20605 * peicode.h (pe_bfd_read_buildid): Check that the Data Directory contains a valid size for the Debug directory. --- bfd/ChangeLog | 6 ++++++ bfd/peicode.h | 27 ++++++++++++++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7414c39..567e18f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-09-14 Nick Clifton + + PR binutils/20605 + * peicode.h (pe_bfd_read_buildid): Check that the Data Directory + contains a valid size for the Debug directory. + 2016-09-14 Bhushan Attarde * format.c (struct bfd_preserve): New "build_id" field. diff --git a/bfd/peicode.h b/bfd/peicode.h index a33e71b..fc8b20f 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1289,7 +1289,7 @@ pe_ILF_object_p (bfd * abfd) } static void -pe_bfd_read_buildid(bfd *abfd) +pe_bfd_read_buildid (bfd *abfd) { pe_data_type *pe = pe_data (abfd); struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; @@ -1306,7 +1306,7 @@ pe_bfd_read_buildid(bfd *abfd) addr += extra->ImageBase; - /* Search for the section containing the DebugDirectory */ + /* Search for the section containing the DebugDirectory. */ for (section = abfd->sections; section != NULL; section = section->next) { if ((addr >= section->vma) && (addr < (section->vma + section->size))) @@ -1314,16 +1314,21 @@ pe_bfd_read_buildid(bfd *abfd) } if (section == NULL) - { - return; - } - else if (!(section->flags & SEC_HAS_CONTENTS)) - { - return; - } + return; + + if (!(section->flags & SEC_HAS_CONTENTS)) + return; dataoff = addr - section->vma; + /* PR 20605: Make sure that the data is really there. */ + if (dataoff + size > section->size) + { + _bfd_error_handler (_("%B: Error: Debug Data ends beyond end of debug directory."), + abfd); + return; + } + /* Read the whole section. */ if (!bfd_malloc_and_get_section (abfd, section, &data)) { @@ -1354,8 +1359,8 @@ pe_bfd_read_buildid(bfd *abfd) (file_ptr) idd.PointerToRawData, idd.SizeOfData, cvinfo)) { - struct bfd_build_id* build_id = bfd_alloc(abfd, - sizeof(struct bfd_build_id) + cvinfo->SignatureLength); + struct bfd_build_id* build_id = bfd_alloc (abfd, + sizeof (struct bfd_build_id) + cvinfo->SignatureLength); if (build_id) { build_id->size = cvinfo->SignatureLength; -- cgit v1.1