You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.7 KiB
124 lines
3.7 KiB
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 de016b5..1f4d1f4 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 2048 |
|
+#define MAX_SHNUM 32768 |
|
+ |
|
+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) |
|
{ |
|
@@ -388,13 +400,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; |
|
} |
|
|
|
|
|
@@ -851,6 +863,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, |
|
Elf32_Shdr sh32; |
|
Elf64_Shdr sh64; |
|
int stripped = 1; |
|
+ size_t nbadcap = 0; |
|
void *nbuf; |
|
off_t noff, coff, name_off; |
|
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ |
|
@@ -928,6 +941,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, |
|
free(nbuf); |
|
break; |
|
case SHT_SUNW_cap: |
|
+ if (nbadcap > 5) |
|
+ break; |
|
if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) { |
|
file_badseek(ms); |
|
return -1; |
|
@@ -963,6 +978,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, |
|
(unsigned long long)xcap_tag, |
|
(unsigned long long)xcap_val) == -1) |
|
return -1; |
|
+ if (nbadcap++ > 2) |
|
+ coff = xsh_size; |
|
break; |
|
} |
|
} |
|
@@ -1142,7 +1159,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;
|
|
|