]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Backport from mainline:
authorDaniel Jacobowitz <drow@false.org>
Mon, 30 May 2005 13:13:17 +0000 (13:13 +0000)
committerDaniel Jacobowitz <drow@false.org>
Mon, 30 May 2005 13:13:17 +0000 (13:13 +0000)
2005-05-29  Jakub Jelinek  <jakub@redhat.com>
* elfcode.h (elf_object_p): Fail if e_shoff != 0, e_shnum == 0 and
first shdr has sh_size == 0.  Fail if e_shnum is large to cause
arithmetic overflow when allocating the i_shdr array.
Sanity check sh_link and sh_info fields.  Fix e_shstrndx sanity check.

2005-05-18  H.J. Lu  <hongjiu.lu@intel.com>
* elf.c (group_signature): Undo the last change. Check if the
symbol table section is correct.

2005-05-17  Nick Clifton  <nickc@redhat.com>
* elf.c (group_signature): Check for a group section which is
actually a (corrupt) symbol table section in disguise and prevent
an infinite loop from occurring.

2005-05-17  Tavis Ormandy <taviso@gentoo.org>
* elf.c (bfd_section_from_shdr): Add sanity check when parsing
dynamic sections.

2005-05-09  Alan Modra  <amodra@bigpond.net.au>
* elfcode.h (elf_object_p): Add more sanity checks on elf header.

bfd/ChangeLog
bfd/elf.c
bfd/elfcode.h

index f983bad12e9776a3e541e8959c93d19c6ec0e6ad..718b8bf831c71c788a209daac42e188c3bd5da96 100644 (file)
@@ -1,3 +1,28 @@
+2005-05-29  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       Backport from mainline:
+       2005-05-29  Jakub Jelinek  <jakub@redhat.com>
+       * elfcode.h (elf_object_p): Fail if e_shoff != 0, e_shnum == 0 and
+       first shdr has sh_size == 0.  Fail if e_shnum is large to cause
+       arithmetic overflow when allocating the i_shdr array.
+       Sanity check sh_link and sh_info fields.  Fix e_shstrndx sanity check.
+
+       2005-05-18  H.J. Lu  <hongjiu.lu@intel.com>
+       * elf.c (group_signature): Undo the last change. Check if the
+       symbol table section is correct.
+
+       2005-05-17  Nick Clifton  <nickc@redhat.com>
+       * elf.c (group_signature): Check for a group section which is
+       actually a (corrupt) symbol table section in disguise and prevent
+       an infinite loop from occurring.
+
+       2005-05-17  Tavis Ormandy <taviso@gentoo.org>
+       * elf.c (bfd_section_from_shdr): Add sanity check when parsing
+       dynamic sections.
+
+       2005-05-09  Alan Modra  <amodra@bigpond.net.au>
+       * elfcode.h (elf_object_p): Add more sanity checks on elf header.
+
 2005-05-28  David Daney  <ddaney@avtrex.com>
 
        * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections):  Move
index f8cc4011565b97e8eb167a2b9d79b6af27370116..49802a85a0897bce63053f02a8bb852741499108 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -443,8 +443,11 @@ group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
   Elf_External_Sym_Shndx eshndx;
   Elf_Internal_Sym isym;
 
-  /* First we need to ensure the symbol table is available.  */
-  if (! bfd_section_from_shdr (abfd, ghdr->sh_link))
+  /* First we need to ensure the symbol table is available.  Make sure
+     that it is a symbol table section.  */
+  hdr = elf_elfsections (abfd) [ghdr->sh_link];
+  if (hdr->sh_type != SHT_SYMTAB
+      || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
     return NULL;
 
   /* Go read the symbol.  */
@@ -1733,6 +1736,9 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
     case SHT_DYNAMIC:  /* Dynamic linking information.  */
       if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
        return FALSE;
+      if (hdr->sh_link > elf_numsections (abfd)
+         || elf_elfsections (abfd)[hdr->sh_link] == NULL)
+       return FALSE;
       if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
        {
          Elf_Internal_Shdr *dynsymhdr;
index fd0dacad5c6679f654cfad5b4fd1bfa0c61a6270..2115fd12bd5cca29d74ce260bc1e57c06b0ca57e 100644 (file)
@@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 /* Problems and other issues to resolve.
 
    (1) BFD expects there to be some fixed number of "sections" in
-        the object file.  I.E. there is a "section_count" variable in the
+       the object file.  I.E. there is a "section_count" variable in the
        bfd structure which contains the number of sections.  However, ELF
        supports multiple "views" of a file.  In particular, with current
        implementations, executable files typically have two tables, a
@@ -612,8 +612,13 @@ elf_object_p (bfd *abfd)
 
   if (i_ehdrp->e_shoff != 0)
     {
+      bfd_signed_vma where = i_ehdrp->e_shoff;
+
+      if (where != (file_ptr) where)
+       goto got_wrong_format_error;
+
       /* Seek to the section header table in the file.  */
-      if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0)
+      if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
        goto got_no_match;
 
       /* Read the first section header at index 0, and convert to internal
@@ -625,11 +630,46 @@ elf_object_p (bfd *abfd)
       /* If the section count is zero, the actual count is in the first
         section header.  */
       if (i_ehdrp->e_shnum == SHN_UNDEF)
-       i_ehdrp->e_shnum = i_shdr.sh_size;
+       {
+         i_ehdrp->e_shnum = i_shdr.sh_size;
+         if (i_ehdrp->e_shnum != i_shdr.sh_size
+             || i_ehdrp->e_shnum == 0)
+           goto got_wrong_format_error;
+       }
 
       /* And similarly for the string table index.  */
       if (i_ehdrp->e_shstrndx == SHN_XINDEX)
-       i_ehdrp->e_shstrndx = i_shdr.sh_link;
+       {
+         i_ehdrp->e_shstrndx = i_shdr.sh_link;
+         if (i_ehdrp->e_shstrndx != i_shdr.sh_link)
+           goto got_wrong_format_error;
+       }
+
+      /* Sanity check that we can read all of the section headers.
+        It ought to be good enough to just read the last one.  */
+      if (i_ehdrp->e_shnum != 1)
+       {
+         /* Check that we don't have a totally silly number of sections.  */
+         if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr)
+             || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr))
+           goto got_wrong_format_error;
+
+         where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
+         if (where != (file_ptr) where)
+           goto got_wrong_format_error;
+         if ((bfd_size_type) where <= i_ehdrp->e_shoff)
+           goto got_wrong_format_error;
+
+         if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+           goto got_no_match;
+         if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
+           goto got_no_match;
+
+         /* Back to where we were.  */
+         where = i_ehdrp->e_shoff + sizeof (x_shdr);
+         if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+           goto got_no_match;
+       }
     }
 
   /* Allocate space for a copy of the section header table in
@@ -673,6 +713,20 @@ elf_object_p (bfd *abfd)
            goto got_no_match;
          elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
 
+         /* Sanity check sh_link and sh_info.  */
+         if (i_shdrp[shindex].sh_link >= num_sec
+             || (i_shdrp[shindex].sh_link >= SHN_LORESERVE
+                 && i_shdrp[shindex].sh_link <= SHN_HIRESERVE))
+           goto got_wrong_format_error;
+
+         if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
+              || i_shdrp[shindex].sh_type == SHT_RELA
+              || i_shdrp[shindex].sh_type == SHT_REL)
+             && (i_shdrp[shindex].sh_info >= num_sec
+                 || (i_shdrp[shindex].sh_info >= SHN_LORESERVE
+                     && i_shdrp[shindex].sh_info <= SHN_HIRESERVE)))
+           goto got_wrong_format_error;
+
          /* If the section is loaded, but not page aligned, clear
             D_PAGED.  */
          if (i_shdrp[shindex].sh_size != 0
@@ -685,6 +739,17 @@ elf_object_p (bfd *abfd)
        }
     }
 
+  /* A further sanity check.  */
+  if (i_ehdrp->e_shnum != 0)
+    {
+      if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)
+         || (i_ehdrp->e_shstrndx >= SHN_LORESERVE
+             && i_ehdrp->e_shstrndx <= SHN_HIRESERVE))
+       goto got_wrong_format_error;
+    }
+  else if (i_ehdrp->e_shstrndx != 0)
+    goto got_wrong_format_error;
+
   /* Read in the program headers.  */
   if (i_ehdrp->e_phnum == 0)
     elf_tdata (abfd)->phdr = NULL;
@@ -1042,7 +1107,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
             symcount);
 
          /* Slurp in the symbols without the version information,
-             since that is more helpful than just quitting.  */
+            since that is more helpful than just quitting.  */
          verhdr = NULL;
        }
 
@@ -1107,7 +1172,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
            sym->symbol.section = bfd_abs_section_ptr;
 
          /* If this is a relocatable file, then the symbol value is
-             already section relative.  */
+            already section relative.  */
          if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
            sym->symbol.value -= sym->symbol.section->vma;