elflint: Sanity check the number of phdrs and shdrs available.
authorMark Wielaard <mark@klomp.org>
Mon, 27 Mar 2017 23:25:34 +0000 (01:25 +0200)
committerMark Wielaard <mark@klomp.org>
Mon, 3 Apr 2017 22:24:02 +0000 (00:24 +0200)
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>
src/ChangeLog
src/elflint.c

index 70744bc..d285e06 100644 (file)
@@ -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.
index 5e95ca9..6c83a77 100644 (file)
@@ -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"),