PR26330, Malloc size error in objdump
authorAlan Modra <amodra@gmail.com>
Mon, 3 Aug 2020 01:31:27 +0000 (11:01 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 3 Aug 2020 04:37:31 +0000 (14:07 +0930)
PR 26330
* elf.c (_bfd_elf_get_symtab_upper_bound): Sanity check symbol table
size against file size.  Correct LONG_MAX limit check.
(_bfd_elf_get_dynamic_symtab_upper_bound): Likewise.
(_bfd_elf_get_reloc_upper_bound): Don't check file size if writing.
(_bfd_elf_get_dynamic_reloc_upper_bound): Likewise.
* elf64-x86-64-.c (elf_x86_64_get_synthetic_symtab): Use
bfd_malloc_and_get_section.

bfd/ChangeLog
bfd/elf.c
bfd/elf64-x86-64.c

index d0a5916d378c03c72791914517390a52c8a2fae5..25cb69fd13f0478c7b447798bc140e620b6b7430 100644 (file)
@@ -1,3 +1,14 @@
+2020-08-03  Alan Modra  <amodra@gmail.com>
+
+       PR 26330
+       * elf.c (_bfd_elf_get_symtab_upper_bound): Sanity check symbol table
+       size against file size.  Correct LONG_MAX limit check.
+       (_bfd_elf_get_dynamic_symtab_upper_bound): Likewise.
+       (_bfd_elf_get_reloc_upper_bound): Don't check file size if writing.
+       (_bfd_elf_get_dynamic_reloc_upper_bound): Likewise.
+       * elf64-x86-64-.c (elf_x86_64_get_synthetic_symtab): Use
+       bfd_malloc_and_get_section.
+
 2020-07-31  Alan Modra  <amodra@gmail.com>
 
        PR 26314
index 5fb1995bad2b267026fd4a14d97ef26e25daaaff..cc2b46ccc7f1555944ce27fdfa00dc0f6c9252e0 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8446,14 +8446,24 @@ _bfd_elf_get_symtab_upper_bound (bfd *abfd)
   Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
 
   symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
-  if (symcount >= LONG_MAX / sizeof (asymbol *))
+  if (symcount > LONG_MAX / sizeof (asymbol *))
     {
       bfd_set_error (bfd_error_file_too_big);
       return -1;
     }
-  symtab_size = (symcount + 1) * (sizeof (asymbol *));
-  if (symcount > 0)
-    symtab_size -= sizeof (asymbol *);
+  symtab_size = symcount * (sizeof (asymbol *));
+  if (symcount == 0)
+    symtab_size = sizeof (asymbol *);
+  else if (!bfd_write_p (abfd))
+    {
+      ufile_ptr filesize = bfd_get_file_size (abfd);
+
+      if (filesize != 0 && (unsigned long) symtab_size > filesize)
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         return -1;
+       }
+    }
 
   return symtab_size;
 }
@@ -8472,14 +8482,24 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
     }
 
   symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
-  if (symcount >= LONG_MAX / sizeof (asymbol *))
+  if (symcount > LONG_MAX / sizeof (asymbol *))
     {
       bfd_set_error (bfd_error_file_too_big);
       return -1;
     }
-  symtab_size = (symcount + 1) * (sizeof (asymbol *));
-  if (symcount > 0)
-    symtab_size -= sizeof (asymbol *);
+  symtab_size = symcount * (sizeof (asymbol *));
+  if (symcount == 0)
+    symtab_size = sizeof (asymbol *);
+  else if (!bfd_write_p (abfd))
+    {
+      ufile_ptr filesize = bfd_get_file_size (abfd);
+
+      if (filesize != 0 && (unsigned long) symtab_size > filesize)
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         return -1;
+       }
+    }
 
   return symtab_size;
 }
@@ -8487,7 +8507,7 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
 long
 _bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
 {
-  if (asect->reloc_count != 0)
+  if (asect->reloc_count != 0 && !bfd_write_p (abfd))
     {
       /* Sanity check reloc section size.  */
       struct bfd_elf_section_data *d = elf_section_data (asect);
@@ -8596,7 +8616,7 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
            return -1;
          }
       }
-  if (count > 1)
+  if (count > 1 && !bfd_write_p (abfd))
     {
       /* Sanity check reloc section sizes.  */
       ufile_ptr filesize = bfd_get_file_size (abfd);
index f97a6a05e87777792ad4ab8256f574d3546e23ff..549a8be6a6a8df4899b40f3d6fa089073bce3ae0 100644 (file)
@@ -4810,15 +4810,8 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
        continue;
 
       /* Get the PLT section contents.  */
-      plt_contents = (bfd_byte *) bfd_malloc (plt->size);
-      if (plt_contents == NULL)
+      if (!bfd_malloc_and_get_section (abfd, plt, &plt_contents))
        break;
-      if (!bfd_get_section_contents (abfd, (asection *) plt,
-                                    plt_contents, 0, plt->size))
-       {
-         free (plt_contents);
-         break;
-       }
 
       /* Check what kind of PLT it is.  */
       plt_type = plt_unknown;