Fix memory access violations exposed by running strip on fuzzed binaries.
authorNick Clifton <nickc@redhat.com>
Thu, 8 Jan 2015 15:39:49 +0000 (15:39 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 8 Jan 2015 15:39:49 +0000 (15:39 +0000)
PR binutils/17512
* coffcode.h (coff_slurp_symbol_table): Return false if we failed
to load the line table.
* elf.c (_bfd_elf_map_sections_to_segments): Enforce a minimum
maxpagesize of 1.
* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Fail if
the Data Directory Size is too large.

* objcopy.c (copy_object): Free the symbol table if no symbols
could be loaded.
(copy_file): Use bfd_close_all_done to close files that could not
be copied.

bfd/ChangeLog
bfd/coffcode.h
bfd/elf.c
bfd/peXXigen.c
binutils/ChangeLog
binutils/objcopy.c

index 3483d79031e71903b50dcf7bdb61e981b0d9dd16..b6151cc33578851b602db584e3bfcb0f889f7b3c 100644 (file)
@@ -1,3 +1,13 @@
+2015-01-08  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/17512
+       * coffcode.h (coff_slurp_symbol_table): Return false if we failed
+       to load the line table.
+       * elf.c (_bfd_elf_map_sections_to_segments): Enforce a minimum
+       maxpagesize of 1.
+       * peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Fail if
+       the Data Directory Size is too large.
+
 2015-01-06  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/17512
index 695497f4b3fd43d8306b67cc9f182db723017811..9e1c20acf38963e4f210ed5299242d5b70b84f3c 100644 (file)
@@ -5012,13 +5012,13 @@ coff_slurp_symbol_table (bfd * abfd)
 #if defined(TIC80COFF) || defined(TICOFF)
            case C_UEXT:        /* Tentative external definition.  */
 #endif
-           case C_EXTLAB:      /* External load time label.  */
-           case C_HIDDEN:      /* Ext symbol in dmert public lib.  */
            default:
              (*_bfd_error_handler)
                (_("%B: Unrecognized storage class %d for %s symbol `%s'"),
                 abfd, src->u.syment.n_sclass,
                 dst->symbol.section->name, dst->symbol.name);
+           case C_EXTLAB:      /* External load time label.  */
+           case C_HIDDEN:      /* Ext symbol in dmert public lib.  */
              dst->symbol.flags = BSF_DEBUGGING;
              dst->symbol.value = (src->u.syment.n_value);
              break;
@@ -5046,7 +5046,8 @@ coff_slurp_symbol_table (bfd * abfd)
     p = abfd->sections;
     while (p)
       {
-       coff_slurp_line_table (abfd, p);
+       if (! coff_slurp_line_table (abfd, p))
+         return FALSE;
        p = p->next;
       }
   }
index f262cc3c7daa09c92283cede8c4025c5ec01a00a..0aa5f8e4791db88841ba00ab8912da7c7e298c99 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4011,6 +4011,11 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       last_size = 0;
       phdr_index = 0;
       maxpagesize = bed->maxpagesize;
+      /* PR 17512: file: c8455299.
+        Avoid divide-by-zero errors later on.
+        FIXME: Should we abort if the maxpagesize is zero ?  */
+      if (maxpagesize == 0)
+       maxpagesize = 1;
       writable = FALSE;
       dynsec = bfd_get_section_by_name (abfd, ".dynamic");
       if (dynsec != NULL
index 09adf8348d772fc5c59242d5cfcb768f669af3d3..0abe609f2e83a367c0b43de087f360df175620e0 100644 (file)
@@ -2930,6 +2930,16 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
           struct external_IMAGE_DEBUG_DIRECTORY *dd =
            (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
 
+         /* PR 17512: file: 0f15796a.  */
+         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)"),
+                                 obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
+                                 bfd_get_section_size (section) - (addr - section->vma));
+             return FALSE;
+           }
+
           for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
                 / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
             {
index d6c3070eb6c6a65f3c8da37cd1e0ea86f3536378..e6fa3c11e5767b37e45b2167cbe9571556b6bdd1 100644 (file)
@@ -1,6 +1,11 @@
 2015-01-08  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/17512
+       * ojcopy.c (copy_object): Free the symbol table if no symbols
+       could be loaded.
+       (copy_file): Use bfd_close_all_done to close files that could not
+       be copied.
+
        * sysdump.c (getINT): Fail if reading off the end of the buffer.
        Replace call to abort with a call to fatal.
        (getCHARS): Prevetn reading off the end of the buffer.
index 25f0131e9bc8bd16c227099dab60c024467483d9..9524bb85de51f531c3b9de9dfb3591c2c9b47f39 100644 (file)
@@ -1776,6 +1776,14 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
       return FALSE;
     }
+  /* PR 17512: file:  d6323821
+     If the symbol table could not be loaded do not pretend that we have
+     any symbols.  This trips us up later on when we load the relocs.  */
+  if (symcount == 0)
+    {
+      free (isympp);
+      osympp = isympp = NULL;
+    }
 
   /* BFD mandates that all output sections be created and sizes set before
      any output is done.  Thus, we traverse all sections multiple times.  */
@@ -2552,7 +2560,11 @@ copy_file (const char *input_filename, const char *output_filename,
       if (! copy_object (ibfd, obfd, input_arch))
        status = 1;
 
-      if (!bfd_close (obfd))
+      /* PR 17512: file: 0f15796a.
+        If the file could not be copied it may not be in a writeable
+        state.  So use bfd_close_all_done to avoid the possibility of
+        writing uninitialised data into the file.  */
+      if (! (status ? bfd_close_all_done (obfd) : bfd_close (obfd)))
        {
          status = 1;
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);