summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2017-03-28 01:25:34 +0200
committerMark Wielaard <mark@klomp.org>2017-04-04 00:24:02 +0200
commit4314716cd498bb51639db717bd7ce6182de33322 (patch)
tree3fc46a11116b9e546e9f2f47ba21768e5d66bf95
parent61fe61898747f63eb35a81c2261f3590a3dab8fd (diff)
downloadelfutils-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/ChangeLog4
-rw-r--r--src/elflint.c26
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"),