* elfcode.h (elf_object_p): Fail if e_shoff != 0, e_shnum == 0 and
authorJakub Jelinek <jakub@redhat.com>
Thu, 26 May 2005 07:41:13 +0000 (07:41 +0000)
committerJakub Jelinek <jakub@redhat.com>
Thu, 26 May 2005 07:41:13 +0000 (07:41 +0000)
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.

bfd/ChangeLog
bfd/elfcode.h

index 40a5e440cf0258621b3ac32f2cdf7c2996568537..0b67df2f9b2065cba9463b94e766c5493df3cc0e 100644 (file)
@@ -1,3 +1,10 @@
+2005-05-26  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-25  Richard Henderson  <rth@redhat.com>
 
        * elf64-alpha.c: Update all function definitions to ISO C.  Remove
index f9e146bc4210873a4275183121821b1956d2fd96..102b215949c9012c918415e5bf4f8835811e08d1 100644 (file)
@@ -632,7 +632,8 @@ elf_object_p (bfd *abfd)
       if (i_ehdrp->e_shnum == SHN_UNDEF)
        {
          i_ehdrp->e_shnum = i_shdr.sh_size;
-         if (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;
        }
 
@@ -649,7 +650,8 @@ elf_object_p (bfd *abfd)
       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))
+         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);
@@ -670,10 +672,6 @@ elf_object_p (bfd *abfd)
        }
     }
 
-  /* A further sanity check.  */
-  if (i_ehdrp->e_shstrndx >= i_ehdrp->e_shnum)
-    goto got_wrong_format_error;
-
   /* Allocate space for a copy of the section header table in
      internal form.  */
   if (i_ehdrp->e_shnum != 0)
@@ -715,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
@@ -727,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;