Make sure we can at least read the shnum sections or phnum segments. Limit the number we do check to those we can actually read.
https://sourceware.org/bugzilla/show_bug.cgi?id=21312 Signed-off-by: Mark Wielaard <m...@klomp.org> --- src/ChangeLog | 4 ++++ src/elflint.c | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index bc9bffb..7034152 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2017-03-27 Mark Wielaard <m...@klomp.org> + * elflint.c (check_elf_header): Sanity check phnum and shnum. + +2017-03-27 Mark Wielaard <m...@klomp.org> + * elflint.c (check_sysv_hash): Return early if section size is too small. (check_sysv_hash64): Likewise. diff --git a/src/elflint.c b/src/elflint.c index 5e95ca9..6c83a77 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -456,6 +456,19 @@ invalid number of section header table entries\n")); ERROR (gettext ("invalid section header index\n")); } + /* Check the shdrs actually exist. */ + unsigned int scnt; + Elf_Scn *scn = NULL; + for (scnt = 1; scnt < shnum; ++scnt) + { + scn = elf_nextscn (ebl->elf, scn); + if (scn == NULL) + break; + } + if (scnt < shnum) + ERROR (gettext ("Can only check %u headers, shnum was %u\n"), scnt, shnum); + shnum = scnt; + phnum = ehdr->e_phnum; if (ehdr->e_phnum == PN_XNUM) { @@ -474,6 +487,19 @@ invalid number of program header table entries\n")); } } + /* Check the phdrs actually exist. */ + unsigned int pcnt; + for (pcnt = 0; pcnt < phnum; ++pcnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); + if (phdr == NULL) + break; + } + if (pcnt < phnum) + ERROR (gettext ("Can only check %u headers, phnum was %u\n"), pcnt, phnum); + phnum = pcnt; + /* Check the e_flags field. */ if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) ERROR (gettext ("invalid machine flags: %s\n"), -- 2.9.3