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] Fixes illegal memory access errors and arithmetic overflows when running strip on fuzzed binaries.


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

commit c86934ceee0971a04bbfc145c7b9a53357c25c91
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Feb 26 21:32:04 2015 +0000

    Fixes illegal memory access errors and arithmetic overflows when running strip on fuzzed binaries.
    
    	PR binutils/17512
    	* coffcode.h (coff_compute_section_file_positions): Report
    	negative page sizes.
    	* elf.c (elf_fake_sections): Handle excessive alignmment powers.
    	(assign_file_positions_for_non_load_sections): Replace assertion
    	with an error message.
    	(rewrite_elf_program_header): Handle excessive segment
    	alignments.
    	* mach-o.c (bfd_mach_o_read_section_32): Likewise.
    	(bfd_mach_o_read_section_64): Likewise.
    	* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Use %B to
    	print a bfd name, not %A.

Diff:
---
 bfd/ChangeLog  | 15 +++++++++++++++
 bfd/coffcode.h |  9 +++++++++
 bfd/elf.c      | 32 ++++++++++++++++++++++++++++----
 bfd/mach-o.c   | 13 +++++++++++++
 bfd/peXXigen.c |  4 ++--
 5 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c2f114a..3916116 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,18 @@
+2015-02-26  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* coffcode.h (coff_compute_section_file_positions): Report
+	negative page sizes.
+	* elf.c (elf_fake_sections): Handle excessive alignmment powers.
+	(assign_file_positions_for_non_load_sections): Replace assertion
+	with an error message.
+	(rewrite_elf_program_header): Handle excessive segment
+	alignments.
+	* mach-o.c (bfd_mach_o_read_section_32): Likewise.
+	(bfd_mach_o_read_section_64): Likewise.
+	* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Use %B to
+	print a bfd name, not %A.
+
 2015-02-26  Alan Modra  <amodra@gmail.com>
 
 	* elf64-ppc.c (plt_stub_size, build_plt_stub): Don't build
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 0ac4ce0..8576c0a 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -3170,6 +3170,15 @@ coff_compute_section_file_positions (bfd * abfd)
 	 This repairs 'ld -r' for arm-wince-pe target.  */
       if (page_size == 0)
 	page_size = 1;
+
+      /* PR 17512: file: 0ac816d3.  */
+      if (page_size < 0)
+	{
+	  bfd_set_error (bfd_error_file_too_big);
+	  (*_bfd_error_handler)
+	    (_("%B: page size is too large (0x%x)"), abfd, page_size);
+	  return FALSE;
+	}
     }
   else
     page_size = PE_DEF_FILE_ALIGNMENT;
diff --git a/bfd/elf.c b/bfd/elf.c
index 14bc531..13d4272 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2758,6 +2758,15 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
   this_hdr->sh_offset = 0;
   this_hdr->sh_size = asect->size;
   this_hdr->sh_link = 0;
+  /* PR 17512: file: 0eb809fe, 8b0535ee.  */
+  if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
+    {
+      (*_bfd_error_handler)
+	(_("%B: error: Alignment power %d of section `%A' is too big"),
+	 abfd, asect, asect->alignment_power);
+      arg->failed = TRUE;
+      return;
+    }
   this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power;
   /* The sh_entsize and sh_info fields may have been set already by
      copy_private_section_data.  */
@@ -5211,7 +5220,14 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 	      && (p->p_type != PT_NOTE
 		  || bfd_get_format (abfd) != bfd_core))
 	    {
-	      BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
+	      if (m->includes_filehdr || m->includes_phdrs)
+		{
+		  /* PR 17512: file: 2195325e.  */ 
+		  (*_bfd_error_handler)
+		    (_("%B: warning: non-load segment includes file header and/or program header"),
+		     abfd);
+		  return FALSE;
+		}
 
 	      p->p_filesz = 0;
 	      p->p_offset = m->sections[0]->filepos;
@@ -5952,8 +5968,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
 	     something.  They are allowed by the ELF spec however, so only
 	     a warning is produced.  */
 	  if (segment->p_type == PT_LOAD)
-	    (*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
-				     " detected, is this intentional ?\n"),
+	    (*_bfd_error_handler) (_("\
+%B: warning: Empty loadable segment detected, is this intentional ?"),
 				   ibfd);
 
 	  map->count = 0;
@@ -6566,7 +6582,15 @@ rewrite:
 	   i++, segment++)
 	if (segment->p_type == PT_LOAD
 	    && maxpagesize < segment->p_align)
-	  maxpagesize = segment->p_align;
+	  {
+	    /* PR 17512: file: f17299af.  */
+	    if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
+	      (*_bfd_error_handler) (_("\
+%B: warning: segment alignment of 0x%llx is too large"),
+				     ibfd, (long long) segment->p_align);
+	    else
+	      maxpagesize = segment->p_align;
+	  }
 
       if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
 	bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 955685f..010a076 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -3469,6 +3469,13 @@ bfd_mach_o_read_section_32 (bfd *abfd,
   section->size = bfd_h_get_32 (abfd, raw.size);
   section->offset = bfd_h_get_32 (abfd, raw.offset);
   section->align = bfd_h_get_32 (abfd, raw.align);
+  /* PR 17512: file: 0017eb76.  */
+  if (section->align > 64)
+    {
+      (*_bfd_error_handler) (_("bfd_mach_o_read_section_32: overlarge alignment value: 0x%x, using 32 instead"),
+			     section->align);
+      section->align = 32;
+    }
   section->reloff = bfd_h_get_32 (abfd, raw.reloff);
   section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
   section->flags = bfd_h_get_32 (abfd, raw.flags);
@@ -3508,6 +3515,12 @@ bfd_mach_o_read_section_64 (bfd *abfd,
   section->size = bfd_h_get_64 (abfd, raw.size);
   section->offset = bfd_h_get_32 (abfd, raw.offset);
   section->align = bfd_h_get_32 (abfd, raw.align);
+  if (section->align > 64)
+    {
+      (*_bfd_error_handler) (_("bfd_mach_o_read_section_64: overlarge alignment value: 0x%x, using 32 instead"),
+			     section->align);
+      section->align = 32;
+    }
   section->reloff = bfd_h_get_32 (abfd, raw.reloff);
   section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
   section->flags = bfd_h_get_32 (abfd, raw.flags);
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index c13c3ff..6aa18ca 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -2955,7 +2955,7 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
 	  if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size + (addr - section->vma)
 	      > bfd_get_section_size (section))
 	    {
-	      _bfd_error_handler (_("%A: Data Directory size (%lx) exceeds space left in section (%lx)"),
+	      _bfd_error_handler (_("%B: Data Directory size (%lx) exceeds space left in section (%lx)"),
 				  obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
 				  bfd_get_section_size (section) - (addr - section->vma));
 	      return FALSE;
@@ -2991,7 +2991,7 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
         }
       else if (section)
 	{
-	  _bfd_error_handler (_("%A: Failed to read debug data section"), obfd);
+	  _bfd_error_handler (_("%B: Failed to read debug data section"), obfd);
 	  return FALSE;
 	}
     }


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