Prevent a memory exhaustion failure when running objdump on a fuzzed input file with...
authorNick Clifton <nickc@redhat.com>
Tue, 8 May 2018 11:51:06 +0000 (12:51 +0100)
committerNick Clifton <nickc@redhat.com>
Tue, 8 May 2018 11:51:06 +0000 (12:51 +0100)
PR 22809
* elf.c (bfd_elf_get_str_section): Check for an excessively large
string section.
* elf-attrs.c (_bfd_elf_parse_attributes): Issue an error if the
attribute section is larger than the size of the file.

bfd/ChangeLog
bfd/elf-attrs.c
bfd/elf.c

index d26c69ab2ac958e91839795621769514e560b77d..e478821a7f8276c625ece1a164e29865b6269d4b 100644 (file)
@@ -1,3 +1,11 @@
+2018-05-08  Nick Clifton  <nickc@redhat.com>
+
+       PR 22809
+       * elf.c (bfd_elf_get_str_section): Check for an excessively large
+       string section.
+       * elf-attrs.c (_bfd_elf_parse_attributes): Issue an error if the
+       attribute section is larger than the size of the file.
+
 2018-05-07  Alan Modra  <amodra@gmail.com>
 
        * cofflink.c (_bfd_coff_link_input_bfd): Use memcmp rather than
index dfdf1a5311ee25f5b629cc742c7e7e2ee12d63f5..b3533095fff2ea4d53d7380c95663515435fde74 100644 (file)
@@ -438,6 +438,15 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
   /* PR 17512: file: 2844a11d.  */
   if (hdr->sh_size == 0)
     return;
+  if (hdr->sh_size > bfd_get_file_size (abfd))
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: error: attribute section '%pA' too big: %#llx"),
+                         abfd, hdr->bfd_section, (long long) hdr->sh_size);
+      bfd_set_error (bfd_error_invalid_operation);
+      return;
+    }
+
   contents = (bfd_byte *) bfd_malloc (hdr->sh_size + 1);
   if (!contents)
     return;
index 21bc4e7ac27638c00d5cb2e26d59b88f22868737..3e8d5103e4d3921a21701a789e7c414397b0d565 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -298,6 +298,7 @@ bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
       /* Allocate and clear an extra byte at the end, to prevent crashes
         in case the string table is not terminated.  */
       if (shstrtabsize + 1 <= 1
+         || shstrtabsize > bfd_get_file_size (abfd)
          || bfd_seek (abfd, offset, SEEK_SET) != 0
          || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL)
        shstrtab = NULL;