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 memory access problems discovered when running some binary tools on corrupt files.


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

commit 4b0e8a5f80441fad8eddaf68e7af70bd6991aa37
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Aug 11 11:57:09 2015 +0100

    Fix memory access problems discovered when running some binary tools on corrupt files.
    
    	PR binutils/18758
    	* elf.c (_bfd_elf_setup_sections): Add checks for corrupt section
    	group information.
    	* peicode.h (pe_ILF_make_a_section): Ensure alignment of the
    	used_by_bfd pointer.
    	(pe_ILF_build_a_bfd): Ensure alignment of vars.data pointer.

Diff:
---
 bfd/ChangeLog |  9 +++++++++
 bfd/elf.c     | 17 +++++++++++++++--
 bfd/peicode.h | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 91d41d3..b3b4239 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2015-08-11  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18758
+	* elf.c (_bfd_elf_setup_sections): Add checks for corrupt section
+	group information.
+	* peicode.h (pe_ILF_make_a_section): Ensure alignment of the
+	used_by_bfd pointer.
+	(pe_ILF_build_a_bfd): Ensure alignment of vars.data pointer.
+
 2015-08-11  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* elf.c (_bfd_elf_copy_private_bfd_data): Fix a typo.
diff --git a/bfd/elf.c b/bfd/elf.c
index 15de37b..7ae2e34 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -817,9 +817,22 @@ _bfd_elf_setup_sections (bfd *abfd)
   for (i = 0; i < num_group; i++)
     {
       Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
-      Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
-      unsigned int n_elt = shdr->sh_size / 4;
+      Elf_Internal_Group *idx;
+      unsigned int n_elt;
 
+      /* PR binutils/18758: Beware of corrupt binaries with invalid group data.  */
+      if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL)
+	{
+	  (*_bfd_error_handler)
+	    (_("%B: section group entry number %u is corrupt"),
+	     abfd, i);
+	  result = FALSE;
+	  continue;
+	}
+
+      idx = (Elf_Internal_Group *) shdr->contents;
+      n_elt = shdr->sh_size / 4;
+      
       while (--n_elt != 0)
 	if ((++idx)->shdr->bfd_section)
 	  elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 06bcaa9..668e742 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -631,6 +631,20 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
   if (size & 1)
     vars->data --;
 
+# if (GCC_VERSION >= 3000)
+  /* PR 18758: See note in pe_ILF_buid_a_bfd.  We must make sure that we
+     preserve host alignment requirements.  We test 'size' rather than
+     vars.data as we cannot perform binary arithmetic on pointers.  We assume
+     that vars.data was sufficiently aligned upon entry to this function.
+     The BFD_ASSERTs in this functions will warn us if we run out of room,
+     but we should already have enough padding built in to ILF_DATA_SIZE.  */
+  {
+    unsigned int alignment = __alignof__ (struct coff_section_tdata);
+
+    if (size & (alignment - 1))
+      vars->data += alignment - (size & (alignment - 1));
+  }
+#endif
   /* Create a coff_section_tdata structure for our use.  */
   sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
   vars->data += sizeof (struct coff_section_tdata);
@@ -836,6 +850,24 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
   /* The remaining space in bim->buffer is used
      by the pe_ILF_make_a_section() function.  */
+# if (GCC_VERSION >= 3000)
+  /* PR 18758: Make sure that the data area is sufficiently aligned for
+     pointers on the host.  __alignof__ is a gcc extension, hence the test
+     above.  For other compilers we will have to assume that the alignment is
+     unimportant, or else extra code can be added here and in
+     pe_ILF_make_a_section.
+
+     Note - we cannot test 'ptr' directly as it is illegal to perform binary
+     arithmetic on pointers, but we know that the strings section is the only
+     one that might end on an unaligned boundary.  */
+  {
+    unsigned int alignment = __alignof__ (char *);
+
+    if (SIZEOF_ILF_STRINGS & (alignment - 1))
+      ptr += alignment - (SIZEOF_ILF_STRINGS & (alignment - 1));
+  }
+#endif
+  
   vars.data = ptr;
   vars.abfd = abfd;
   vars.sec_index = 0;


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