From 24639c7dfef1a7640481cfc2723879f9ffe0ae1c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 26 May 2005 07:41:13 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 7 +++++++ bfd/elfcode.h | 35 +++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 40a5e440cf..0b67df2f9b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2005-05-26 Jakub Jelinek + + * 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 * elf64-alpha.c: Update all function definitions to ISO C. Remove diff --git a/bfd/elfcode.h b/bfd/elfcode.h index f9e146bc42..102b215949 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -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;