commit:     18ded0e30ee5a84260cceb80d818b9c21ade4c76
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Wed Feb  1 20:05:09 2017 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Wed Feb  1 20:05:09 2017 +0000
URL:        https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=18ded0e3

dumpelf: check for invalid program headers

URL: https://bugs.gentoo.org/607896
Reported-by: Agostino Sarubbo <ago <AT> gentoo.org>

 dumpelf.c | 8 ++++----
 paxelf.h  | 5 +++++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/dumpelf.c b/dumpelf.c
index 44da3ee..a9c6e05 100644
--- a/dumpelf.c
+++ b/dumpelf.c
@@ -293,9 +293,6 @@ static void dump_phdr(elfobj *elf, const void *phdr_void, 
size_t phdr_cnt)
        Elf ## B ## _Off offset = EGET(phdr->p_offset); \
        void *vdata = elf->vdata + offset; \
        uint32_t p_type = EGET(phdr->p_type); \
-       switch (p_type) { \
-       case PT_DYNAMIC: phdr_dynamic_void = phdr_void; break; \
-       } \
        printf("/* Program Header #%zu 0x%tX */\n{\n", \
               phdr_cnt, (uintptr_t)phdr_void - elf->udata); \
        printf("\t.p_type   = %-10u , /* [%s] */\n", p_type, 
get_elfptype(p_type)); \
@@ -307,12 +304,15 @@ static void dump_phdr(elfobj *elf, const void *phdr_void, 
size_t phdr_cnt)
        printf("\t.p_flags  = 0x%-8X , /* %s */\n", 
(uint32_t)EGET(phdr->p_flags), dump_p_flags(p_type, EGET(phdr->p_flags))); \
        printf("\t.p_align  = %-10"PRIu64" , /* (min mem alignment in bytes) 
*/\n", EGET(phdr->p_align)); \
        \
-       if ((off_t)EGET(phdr->p_offset) > elf->len) { \
+       if (!VALID_PHDR(elf, phdr)) { \
                printf("\t/* Warning: Program segment is corrupt. */\n"); \
                goto done##B; \
        } \
        \
        switch (p_type) { \
+       case PT_DYNAMIC: \
+               phdr_dynamic_void = phdr_void; \
+               break; \
        case PT_NOTE: \
                dump_notes(elf, B, vdata, vdata + EGET(phdr->p_filesz)); \
                break; \

diff --git a/paxelf.h b/paxelf.h
index 56fa9f3..90b283c 100644
--- a/paxelf.h
+++ b/paxelf.h
@@ -45,6 +45,11 @@ typedef struct {
         EGET(shdr->sh_offset) < (uint64_t)elf->len && \
         EGET(shdr->sh_size) < (uint64_t)elf->len && \
         EGET(shdr->sh_offset) <= elf->len - EGET(shdr->sh_size))
+#define VALID_PHDR(elf, phdr) \
+       (phdr && \
+        EGET(phdr->p_filesz) < (uint64_t)elf->len && \
+        EGET(phdr->p_offset) < (uint64_t)elf->len && \
+        EGET(phdr->p_filesz) <= elf->len - EGET(phdr->p_offset))
 
 /* prototypes */
 extern char *pax_short_hf_flags(unsigned long flags);

Reply via email to