123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- Subject: Limit the number of program and section header number of sections to be (...)
- ID: CVE-2014-8116
- Upstream-Author: Christos Zoulas <christos@zoulas.com>
- Date: Sat Nov 22 16:04:29 2014 +0000
- Origin: FILE5_20-27-gb4c0114
- Last-Update: 2015-01-05
- - limit the number of program and section header number of sections to be
- processed to avoid excessive processing time.
- - if a bad note is found, return 0 to stop processing immediately.
- diff --git a/src/elfclass.h b/src/elfclass.h
- index 010958a..0826ce3 100644
- --- a/src/elfclass.h
- +++ b/src/elfclass.h
- @@ -35,10 +35,12 @@
- 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;
- @@ -46,18 +48,24 @@
- #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)
- diff --git a/src/readelf.c b/src/readelf.c
- index 18dacdd..5a6dd41 100644
- --- a/src/readelf.c
- +++ b/src/readelf.c
- @@ -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)
- {
- @@ -507,13 +519,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;
- }
-
-
- @@ -1198,7 +1210,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;
|