summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2005-05-30 13:13:17 +0000
committerDaniel Jacobowitz <dan@debian.org>2005-05-30 13:13:17 +0000
commit9b0f292387e5d8c59feb0a07d619d2cb66500b3c (patch)
tree9b57431a8f0611b0357ad7f74654be72e8dffb25
parent59c7a4d5449eb773679c4217b104f5bf3ec0ab91 (diff)
downloadgdb-9b0f292387e5d8c59feb0a07d619d2cb66500b3c.tar.gz
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.
-rw-r--r--bfd/ChangeLog25
-rw-r--r--bfd/elf.c10
-rw-r--r--bfd/elfcode.h77
3 files changed, 104 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f983bad12e9..718b8bf831c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf.c b/bfd/elf.c
index f8cc4011565..49802a85a08 100644
--- 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;
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index fd0dacad5c6..2115fd12bd5 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -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;