From: Nick Clifton Date: Wed, 14 Sep 2016 14:32:01 +0000 (+0100) Subject: Fix seg-fault in objdump when run on a fuzzed PE binary. X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=e6d042fe27102cb789407ccb2ec1663aa9c65129;hp=fc7514d6f2784390b7e6c65c0c9603ede0203f58;p=deliverable%2Fbinutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7414c39f37..567e18f195 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 a33e71bebe..fc8b20f7f6 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;