Prevent attempts to allocate excessive amounts of memory when parsing corrupt ELF...
authorNick Clifton <nickc@redhat.com>
Fri, 28 Jun 2019 14:30:43 +0000 (15:30 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 28 Jun 2019 14:30:43 +0000 (15:30 +0100)
PR 24708
* elf.c (_bfd_elf_slurp_version_tables): Check for an excessively
large version reference section.
* compress.c (bfd_get_full_section_contents): Check for an
uncompressed section whose size is larger than the file size.

bfd/ChangeLog
bfd/compress.c
bfd/elf.c
binutils/ChangeLog
binutils/objdump.c

index 04bdb78607676cebf37e78dd26a1b9447e27dd63..31d4eee240aa96b7a8114f8f1d760ed7fc458c85 100644 (file)
@@ -1,3 +1,11 @@
+2019-06-28  Nick Clifton  <nickc@redhat.com>
+
+       PR 24708
+       * elf.c (_bfd_elf_slurp_version_tables): Check for an excessively
+       large version reference section.
+       * compress.c (bfd_get_full_section_contents): Check for an
+       uncompressed section whose size is larger than the file size.
+
 2019-06-28  Alan Modra  <amodra@gmail.com>
 
        * format.c (bfd_check_format_matches): Don't match plugin target
index b5db7a76bedc71307768299d9e738192c3c210bf..cba281dca49348ab216f24b5669ec7687133fad6 100644 (file)
@@ -250,6 +250,23 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
     case COMPRESS_SECTION_NONE:
       if (p == NULL)
        {
+         ufile_ptr filesize = bfd_get_file_size (abfd);
+         if (filesize > 0
+             && filesize < sz
+             /* The MMO file format supports its own special compression
+                technique, but it uses COMPRESS_SECTION_NONE when loading
+                a section's contents.  */
+             && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
+           {
+             /* PR 24708: Avoid attempts to allocate a ridiculous amount
+                of memory.  */
+             bfd_set_error (bfd_error_no_memory);
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"),
+                abfd, sec, (uint64_t) sz, (uint64_t) filesize);
+             return FALSE;
+           }
          p = (bfd_byte *) bfd_malloc (sz);
          if (p == NULL)
            {
index 2094fca1ff54bb077c8750993d3d46a30e73cb8a..75efcc6f105bcf9b61bee9c2995ccb8ecf6e7dd8 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8443,6 +8443,18 @@ error_return_verref:
          goto error_return;
        }
 
+      ufile_ptr filesize = bfd_get_file_size (abfd);
+      if (filesize > 0 && filesize < hdr->sh_size)
+       {
+         /* PR 24708: Avoid attempts to allocate a ridiculous amount
+            of memory.  */
+         bfd_set_error (bfd_error_no_memory);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("error: %pB version reference section is too large (%#" PRIx64 " bytes)"),
+            abfd, (uint64_t) hdr->sh_size);
+         goto error_return_verref;
+       }
       contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
       if (contents == NULL)
        goto error_return_verref;
index e9f83e6413f95c0fb509a6940fed3adaaec07441..d7231713e7a4d6d23e20e0710048f31abeecfe13 100644 (file)
@@ -2,7 +2,8 @@
 
        PR 24707
        * objdump.c (slurp_symtab): Fail with a helpful error message if
-       the symbol table is too large.
+       the symbol table is too large.  Skip this check for MMO format
+       files.
 
 2019-06-26  Nick Clifton  <nickc@redhat.com>
 
index 32e6f24f7b4744cc9a8090b142396b0e1e5ca356..6812ba7853de6cbaad86dec915a6bec59729fdc1 100644 (file)
@@ -708,7 +708,11 @@ slurp_symtab (bfd *abfd)
       off_t filesize = bfd_get_file_size (abfd);
 
       /* qv PR 24707.  */
-      if (filesize > 0 && filesize < storage)
+      if (filesize > 0
+         && filesize < storage
+         /* The MMO file format supports its own special compression
+            technique, so its sections can be larger than the file size.  */
+         && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)    
        {
          bfd_nonfatal_message (bfd_get_filename (abfd), abfd, NULL,
                                _("error: symbol table size (%#lx) is larger than filesize (%#lx)"),