This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix address violations when atempting to parse fuzzed binaries.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cfd14a500e0485374596234de4db10e88ebc7618

commit cfd14a500e0485374596234de4db10e88ebc7618
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Jun 26 15:25:08 2017 +0100

    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.

Diff:
---
 bfd/ChangeLog      | 10 ++++++++++
 bfd/compress.c     |  6 ++++++
 bfd/elf32-v850.c   |  4 +++-
 bfd/opncls.c       | 18 ++++++++++++++++--
 binutils/ChangeLog |  6 ++++++
 binutils/objdump.c |  4 ++--
 6 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b8624c8..8a4352f 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 c854a20..7b2c37c 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 0e9ed5f..8db7507 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 994b950..913341c 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 6810c22..af2a348 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 16e1f0e..ed8c645 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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]