PR26348, Malloc error in write_zeros

Alan Modra amodra@gmail.com
Wed Aug 12 14:22:06 GMT 2020


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.

diff --git a/bfd/bfd.c b/bfd/bfd.c
index 538bdfa5d7..ec38a0673c 100644
--- 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;
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 2e2c5343f2..84b08b57eb 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -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);
+	    }
 	}
     }
 
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 3866c7f458..c5af179b17 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -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;
     }
 

-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list