summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2005-05-09 03:35:38 +0000
committerAlan Modra <amodra@gmail.com>2005-05-09 03:35:38 +0000
commit0560d0f70c85c47dad453171c128c322a099a9fa (patch)
tree5b1355bef2d635c2bdfdbd51e3a4b982597b7607
parenta2b910671769680a77431eaef9239a6ef1ed751b (diff)
* elfcode.h (elf_object_p): Add more sanity checks on elf header.
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/elfcode.h54
2 files changed, 52 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8563a0f97d..7ab00f0993 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,7 @@
+2005-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (elf_object_p): Add more sanity checks on elf header.
+
2005-05-08 Dave Korn <dave.korn@artimi.com>
* coff-tic80.c: Undefine _CONST after system headers to prevent
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index fb9b89da81..f9e146bc42 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -33,7 +33,7 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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,13 +630,50 @@ 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)
+ 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))
+ 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;
+ }
}
+ /* 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)
@@ -1042,7 +1084,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 +1149,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;