diff options
author | Mark Wielaard <mark@klomp.org> | 2017-03-28 01:25:34 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2017-04-04 00:24:02 +0200 |
commit | 4314716cd498bb51639db717bd7ce6182de33322 (patch) | |
tree | 3fc46a11116b9e546e9f2f47ba21768e5d66bf95 | |
parent | 61fe61898747f63eb35a81c2261f3590a3dab8fd (diff) | |
download | elfutils-4314716cd498bb51639db717bd7ce6182de33322.tar.gz |
elflint: Sanity check the number of phdrs and shdrs available.
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 <mark@klomp.org>
-rw-r--r-- | src/ChangeLog | 4 | ||||
-rw-r--r-- | src/elflint.c | 26 |
2 files changed, 30 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 70744bcf..d285e068 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2017-03-27 Mark Wielaard <mark@klomp.org> + * elflint.c (check_elf_header): Sanity check phnum and shnum. + +2017-03-27 Mark Wielaard <mark@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 5e95ca95..6c83a773 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"), |