aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2017-06-26 15:25:08 +0100
committerNick Clifton <nickc@redhat.com>2017-06-26 15:25:08 +0100
commitcfd14a500e0485374596234de4db10e88ebc7618 (patch)
tree5627cf743e8fc9646606e13bd6227fe959636bd5
parent0602cdad745472ed2561d8096a4bb021c8d0301d (diff)
Fix address violations when atempting to parse fuzzed binaries.
PR binutils/21665 bfd * opncls.c (get_build_id): Check that the section is beig enough to contain the whole note. * compress.c (bfd_get_full_section_contents): Check for and reject a section whoes size is greater than the size of the entire file. * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not contain a notes section. binutils* objdump.c (disassemble_section): Skip any section that is bigger than the entire file.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/compress.c6
-rw-r--r--bfd/elf32-v850.c4
-rw-r--r--bfd/opncls.c18
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/objdump.c4
6 files changed, 43 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b8624c8be6..8a4352f494 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2017-06-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/21665
+ * opncls.c (get_build_id): Check that the section is beig enough
+ to contain the whole note.
+ * compress.c (bfd_get_full_section_contents): Check for and reject
+ a section whoes size is greater than the size of the entire file.
+ * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not
+ contain a notes section.
+
2017-06-26 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf64-s390.c (elf_s390_additional_program_headers): Add NULL
diff --git a/bfd/compress.c b/bfd/compress.c
index c854a204fd..7b2c37c418 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -239,6 +239,12 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
*ptr = NULL;
return TRUE;
}
+ else if (bfd_get_file_size (abfd) > 0
+ && sz > (bfd_size_type) bfd_get_file_size (abfd))
+ {
+ *ptr = NULL;
+ return FALSE;
+ }
switch (sec->compress_status)
{
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
index 0e9ed5f05a..8db7507800 100644
--- a/bfd/elf32-v850.c
+++ b/bfd/elf32-v850.c
@@ -2450,7 +2450,9 @@ v850_elf_copy_notes (bfd *ibfd, bfd *obfd)
BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont));
if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL)
- BFD_ASSERT (bfd_malloc_and_get_section (obfd, onotes, & ocont));
+ /* If the output is being stripped then it is possible for
+ the notes section to disappear. In this case do nothing. */
+ return;
/* Copy/overwrite notes from the input to the output. */
memcpy (ocont, icont, bfd_section_size (obfd, onotes));
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 994b950ba3..913341c9ff 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -1825,6 +1825,7 @@ get_build_id (bfd *abfd)
Elf_External_Note *enote;
bfd_byte *contents;
asection *sect;
+ bfd_size_type size;
BFD_ASSERT (abfd);
@@ -1839,8 +1840,9 @@ get_build_id (bfd *abfd)
return NULL;
}
+ size = bfd_get_section_size (sect);
/* FIXME: Should we support smaller build-id notes ? */
- if (bfd_get_section_size (sect) < 0x24)
+ if (size < 0x24)
{
bfd_set_error (bfd_error_invalid_operation);
return NULL;
@@ -1853,6 +1855,17 @@ get_build_id (bfd *abfd)
return NULL;
}
+ /* FIXME: Paranoia - allow for compressed build-id sections.
+ Maybe we should complain if this size is different from
+ the one obtained above... */
+ size = bfd_get_section_size (sect);
+ if (size < sizeof (Elf_External_Note))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ free (contents);
+ return NULL;
+ }
+
enote = (Elf_External_Note *) contents;
inote.type = H_GET_32 (abfd, enote->type);
inote.namesz = H_GET_32 (abfd, enote->namesz);
@@ -1864,7 +1877,8 @@ get_build_id (bfd *abfd)
if (inote.descsz == 0
|| inote.type != NT_GNU_BUILD_ID
|| inote.namesz != 4 /* sizeof "GNU" */
- || strcmp (inote.namedata, "GNU") != 0)
+ || strncmp (inote.namedata, "GNU", 4) != 0
+ || size < (12 + BFD_ALIGN (inote.namesz, 4) + inote.descsz))
{
free (contents);
bfd_set_error (bfd_error_invalid_operation);
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6810c22154..af2a348d5b 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,11 @@
2017-06-26 Nick Clifton <nickc@redhat.com>
+ PR binutils/21665
+ * objdump.c (disassemble_section): Skip any section that is bigger
+ than the entire file.
+
+2017-06-26 Nick Clifton <nickc@redhat.com>
+
PR binutils/21659
* bucomm.c (get_file_size): Explicitly warn if the file is a
directory.
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 16e1f0ea9f..ed8c645897 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -2114,7 +2114,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
return;
datasize = bfd_get_section_size (section);
- if (datasize == 0)
+ if (datasize == 0 || datasize >= (bfd_size_type) bfd_get_file_size (abfd))
return;
if (start_address == (bfd_vma) -1
@@ -2985,7 +2985,7 @@ dump_target_specific (bfd *abfd)
static void
dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
{
- bfd_byte *data = 0;
+ bfd_byte *data = NULL;
bfd_size_type datasize;
bfd_vma addr_offset;
bfd_vma start_offset;