PR26348, Malloc error in write_zeros
authorAlan Modra <amodra@gmail.com>
Wed, 12 Aug 2020 10:48:43 +0000 (20:18 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 12 Aug 2020 22:39:08 +0000 (08:09 +0930)
This adds a few more sanity checks on ELF objects, and a BFD flag to
disable objcopy and strip when fuzzed input files belong in the "too
hard" basket.

bfd/
PR 26348
* bfd.c (struct bfd): Add read_only.
* elfcode.h (elf_swap_shdr_in): Test both sh_offset and sh_size.
Set read_only on warning.
(elf_object_p): Sanity check program header alignment.  Set
read_only on warning.
* bfd-in2.h: Regenerate.
binutils/
PR 26348
* objcopy.c (copy_object): Report file name with endian error.
Error and return on abfd->read_only.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/elfcode.h
binutils/ChangeLog
binutils/objcopy.c

index a2342588e80888a3ef643d990c29e526083add05..0e22506e02210c029b050013cfc925c63f4723d8 100644 (file)
@@ -1,3 +1,13 @@
+2020-08-13  Alan Modra  <amodra@gmail.com>
+
+       PR 26348
+       * bfd.c (struct bfd): Add read_only.
+       * elfcode.h (elf_swap_shdr_in): Test both sh_offset and sh_size.
+       Set read_only on warning.
+       (elf_object_p): Sanity check program header alignment.  Set
+       read_only on warning.
+       * bfd-in2.h: Regenerate.
+
 2020-08-12  Jon Turney  <jon.turney@dronecode.org.uk>
 
        * elf.c (elfcore_grok_win32pstatus): Use unsigned int for
index 35ef4d755bb180d37e5d2a4adfa8adf342d2473f..94d3195836a4d19882f0a03b716ce795cb340e02 100644 (file)
@@ -6678,6 +6678,10 @@ struct bfd
   /* Set if this is a slim LTO object not loaded with a compiler plugin.  */
   unsigned int lto_slim_object : 1;
 
+  /* Do not attempt to modify this file.  Set when detecting errors
+     that BFD is not prepared to handle for objcopy/strip.  */
+  unsigned int read_only : 1;
+
   /* Set to dummy BFD created when claimed by a compiler plug-in
      library.  */
   bfd *plugin_dummy_bfd;
index 538bdfa5d7df9dfbd3fb1e73bf57e145a4fc543e..ec38a0673c7ad606449a4c39ddfd75f7b08a0d89 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -245,6 +245,10 @@ CODE_FRAGMENT
 .  {* Set if this is a slim LTO object not loaded with a compiler plugin.  *}
 .  unsigned int lto_slim_object : 1;
 .
+.  {* Do not attempt to modify this file.  Set when detecting errors
+.     that BFD is not prepared to handle for objcopy/strip.  *}
+.  unsigned int read_only : 1;
+.
 .  {* Set to dummy BFD created when claimed by a compiler plug-in
 .     library.  *}
 .  bfd *plugin_dummy_bfd;
index 2e2c5343f2ce5f1727dc64161f710e47d7296dae..84b08b57ebce9a9df05fd968ed26417a105f4419 100644 (file)
@@ -321,11 +321,14 @@ elf_swap_shdr_in (bfd *abfd,
     {
       ufile_ptr filesize = bfd_get_file_size (abfd);
 
-      if (filesize != 0 && dst->sh_size > filesize)
-       _bfd_error_handler
-         (_("warning: %pB has a corrupt section with a size (%"
-            BFD_VMA_FMT "x) larger than the file size"),
-          abfd, dst->sh_size);
+      if (filesize != 0
+         && ((ufile_ptr) dst->sh_offset > filesize
+             || dst->sh_size > filesize - dst->sh_offset))
+       {
+         abfd->read_only = 1;
+         _bfd_error_handler (_("warning: %pB has a section "
+                               "extending past end of file"), abfd);
+       }
     }
   dst->sh_link = H_GET_32 (abfd, src->sh_link);
   dst->sh_info = H_GET_32 (abfd, src->sh_info);
@@ -764,6 +767,7 @@ elf_object_p (bfd *abfd)
             So we are kind, and reset the string index value to 0
             so that at least some processing can be done.  */
          i_ehdrp->e_shstrndx = SHN_UNDEF;
+         abfd->read_only = 1;
          _bfd_error_handler
            (_("warning: %pB has a corrupt string table index - ignoring"),
             abfd);
@@ -804,6 +808,14 @@ elf_object_p (bfd *abfd)
          if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
            goto got_no_match;
          elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
+         /* Too much code in BFD relies on alignment being a power of
+            two, as required by the ELF spec.  */
+         if (i_phdr->p_align != (i_phdr->p_align & -i_phdr->p_align))
+           {
+             abfd->read_only = 1;
+             _bfd_error_handler (_("warning: %pB has a program header "
+                                   "with invalid alignment"), abfd);
+           }
        }
     }
 
index 5037d91e0dd62534f18f4e2e8c9de899a4f45453..0006ad1740f510a7be08e04d7eec0475f280c813 100644 (file)
@@ -1,3 +1,9 @@
+2020-08-13  Alan Modra  <amodra@gmail.com>
+
+       PR 26348
+       * objcopy.c (copy_object): Report file name with endian error.
+       Error and return on abfd->read_only.
+
 2020-08-12  Tom Tromey  <tromey@adacore.com>
 
        * dwarf-mode.el (Version): Now 1.6.
index 3866c7f458861dd522a44e07b20d8485f66719b1..c5af179b17e0690372cf40141ead226c2127e5f2 100644 (file)
@@ -2604,7 +2604,15 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
     {
       /* PR 17636: Call non-fatal so that we return to our parent who
         may need to tidy temporary files.  */
-      non_fatal (_("Unable to change endianness of input file(s)"));
+      non_fatal (_("unable to change endianness of '%s'"),
+                bfd_get_archive_filename (ibfd));
+      return FALSE;
+    }
+
+  if (ibfd->read_only)
+    {
+      non_fatal (_("unable to modify '%s' due to errors"),
+                bfd_get_archive_filename (ibfd));
       return FALSE;
     }