[binutils-gdb] PR26330, Malloc size error in objdump

Alan Modra amodra@sourceware.org
Mon Aug 3 07:41:24 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b5f386d52049067ca081651a460ab4ae85e327d4

commit b5f386d52049067ca081651a460ab4ae85e327d4
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Aug 3 11:01:27 2020 +0930

    PR26330, Malloc size error in objdump
    
            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.

Diff:
---
 bfd/ChangeLog      | 11 +++++++++++
 bfd/elf.c          | 40 ++++++++++++++++++++++++++++++----------
 bfd/elf64-x86-64.c |  9 +--------
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d0a5916d378..25cb69fd13f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf.c b/bfd/elf.c
index 5fb1995bad2..cc2b46ccc7f 100644
--- 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);
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index f97a6a05e87..549a8be6a6a 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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;


More information about the Binutils-cvs mailing list