aboutsummaryrefslogtreecommitdiff
path: root/bfd/peicode.h
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2016-09-14 15:32:01 +0100
committerNick Clifton <nickc@redhat.com>2016-09-14 15:32:01 +0100
commite6d042fe27102cb789407ccb2ec1663aa9c65129 (patch)
treeb94536264ce84eb6a3a0a029c60bc878012f7ecf /bfd/peicode.h
parentfc7514d6f2784390b7e6c65c0c9603ede0203f58 (diff)
downloadgdb-e6d042fe27102cb789407ccb2ec1663aa9c65129.zip
gdb-e6d042fe27102cb789407ccb2ec1663aa9c65129.tar.gz
gdb-e6d042fe27102cb789407ccb2ec1663aa9c65129.tar.bz2
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.
Diffstat (limited to 'bfd/peicode.h')
-rw-r--r--bfd/peicode.h27
1 files changed, 16 insertions, 11 deletions
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;