]> granicus.if.org Git - file/commitdiff
- limit the number of program and section header number of sections to be
authorChristos Zoulas <christos@zoulas.com>
Sat, 22 Nov 2014 16:04:29 +0000 (16:04 +0000)
committerChristos Zoulas <christos@zoulas.com>
Sat, 22 Nov 2014 16:04:29 +0000 (16:04 +0000)
  processed to avoid excessive processing time.
- if a bad note is found, return 0 to stop processing immediately.

src/elfclass.h
src/readelf.c

index 010958a4296fb8872a0203cc928617cb268fb6d8..0826ce3213a5c0e8a57d7673666232d038fdbd89 100644 (file)
        switch (type) {
 #ifdef ELFCORE
        case ET_CORE:
+               phnum = elf_getu16(swap, elfhdr.e_phnum);
+               if (phnum > MAX_PHNUM)
+                       return toomany(ms, "program", phnum);
                flags |= FLAGS_IS_CORE;
                if (dophn_core(ms, clazz, swap, fd,
-                   (off_t)elf_getu(swap, elfhdr.e_phoff),
-                   elf_getu16(swap, elfhdr.e_phnum), 
+                   (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
                    (size_t)elf_getu16(swap, elfhdr.e_phentsize),
                    fsize, &flags) == -1)
                        return -1;
 #endif
        case ET_EXEC:
        case ET_DYN:
+               phnum = elf_getu16(swap, elfhdr.e_phnum);
+               if (phnum > MAX_PHNUM)
+                       return toomany(ms, "program", phnum);
+               shnum = elf_getu16(swap, elfhdr.e_shnum);
+               if (shnum > MAX_SHNUM)
+                       return toomany(ms, "section", shnum);
                if (dophn_exec(ms, clazz, swap, fd,
-                   (off_t)elf_getu(swap, elfhdr.e_phoff),
-                   elf_getu16(swap, elfhdr.e_phnum), 
+                   (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
                    (size_t)elf_getu16(swap, elfhdr.e_phentsize),
-                   fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
-                   == -1)
+                   fsize, &flags, shnum) == -1)
                        return -1;
                /*FALLTHROUGH*/
        case ET_REL:
+               shnum = elf_getu16(swap, elfhdr.e_shnum);
+               if (shnum > MAX_SHNUM)
+                       return toomany(ms, "section", shnum);
                if (doshn(ms, clazz, swap, fd,
-                   (off_t)elf_getu(swap, elfhdr.e_shoff),
-                   elf_getu16(swap, elfhdr.e_shnum),
+                   (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
                    (size_t)elf_getu16(swap, elfhdr.e_shentsize),
                    fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
                    (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
index ff58c828ebdd0d7bb6448b2a82db4804092cb826..5bb2d56d76fcdc240da296d906f58310b3f5cd3d 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.104 2014/10/17 15:49:00 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.105 2014/11/22 16:04:29 christos Exp $")
 #endif
 
 #ifdef BUILTIN_ELF
@@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t);
 private uint32_t getu32(int, uint32_t);
 private uint64_t getu64(int, uint64_t);
 
+#define MAX_PHNUM      256
+#define        MAX_SHNUM       1024
+
+private int
+toomany(struct magic_set *ms, const char *name, uint16_t num)
+{
+       if (file_printf(ms, ", too many %s header sections (%u)", name, num
+           ) == -1)
+               return -1;
+       return 0;
+}
+
 private uint16_t
 getu16(int swap, uint16_t value)
 {
@@ -499,13 +511,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
        if (namesz & 0x80000000) {
            (void)file_printf(ms, ", bad note name size 0x%lx",
                (unsigned long)namesz);
-           return offset;
+           return 0;
        }
 
        if (descsz & 0x80000000) {
            (void)file_printf(ms, ", bad note description size 0x%lx",
                (unsigned long)descsz);
-           return offset;
+           return 0;
        }
 
 
@@ -1240,7 +1252,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
        int flags = 0;
        Elf32_Ehdr elf32hdr;
        Elf64_Ehdr elf64hdr;
-       uint16_t type;
+       uint16_t type, phnum, shnum;
 
        if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
                return 0;