|
|
89be67 |
diff --git a/src/elfclass.h b/src/elfclass.h
|
|
|
89be67 |
index 010958a..0826ce3 100644
|
|
|
89be67 |
--- a/src/elfclass.h
|
|
|
89be67 |
+++ b/src/elfclass.h
|
|
|
89be67 |
@@ -35,10 +35,12 @@
|
|
|
89be67 |
switch (type) {
|
|
|
89be67 |
#ifdef ELFCORE
|
|
|
89be67 |
case ET_CORE:
|
|
|
89be67 |
+ phnum = elf_getu16(swap, elfhdr.e_phnum);
|
|
|
89be67 |
+ if (phnum > MAX_PHNUM)
|
|
|
89be67 |
+ return toomany(ms, "program", phnum);
|
|
|
89be67 |
flags |= FLAGS_IS_CORE;
|
|
|
89be67 |
if (dophn_core(ms, clazz, swap, fd,
|
|
|
89be67 |
- (off_t)elf_getu(swap, elfhdr.e_phoff),
|
|
|
89be67 |
- elf_getu16(swap, elfhdr.e_phnum),
|
|
|
89be67 |
+ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
|
|
|
89be67 |
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
|
|
|
89be67 |
fsize, &flags) == -1)
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
@@ -46,18 +48,24 @@
|
|
|
89be67 |
#endif
|
|
|
89be67 |
case ET_EXEC:
|
|
|
89be67 |
case ET_DYN:
|
|
|
89be67 |
+ phnum = elf_getu16(swap, elfhdr.e_phnum);
|
|
|
89be67 |
+ if (phnum > MAX_PHNUM)
|
|
|
89be67 |
+ return toomany(ms, "program", phnum);
|
|
|
89be67 |
+ shnum = elf_getu16(swap, elfhdr.e_shnum);
|
|
|
89be67 |
+ if (shnum > MAX_SHNUM)
|
|
|
89be67 |
+ return toomany(ms, "section", shnum);
|
|
|
89be67 |
if (dophn_exec(ms, clazz, swap, fd,
|
|
|
89be67 |
- (off_t)elf_getu(swap, elfhdr.e_phoff),
|
|
|
89be67 |
- elf_getu16(swap, elfhdr.e_phnum),
|
|
|
89be67 |
+ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
|
|
|
89be67 |
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
|
|
|
89be67 |
- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
|
|
|
89be67 |
- == -1)
|
|
|
89be67 |
+ fsize, &flags, shnum) == -1)
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
/*FALLTHROUGH*/
|
|
|
89be67 |
case ET_REL:
|
|
|
89be67 |
+ shnum = elf_getu16(swap, elfhdr.e_shnum);
|
|
|
89be67 |
+ if (shnum > MAX_SHNUM)
|
|
|
89be67 |
+ return toomany(ms, "section", shnum);
|
|
|
89be67 |
if (doshn(ms, clazz, swap, fd,
|
|
|
89be67 |
- (off_t)elf_getu(swap, elfhdr.e_shoff),
|
|
|
89be67 |
- elf_getu16(swap, elfhdr.e_shnum),
|
|
|
89be67 |
+ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
|
|
|
89be67 |
(size_t)elf_getu16(swap, elfhdr.e_shentsize),
|
|
|
89be67 |
fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
|
|
|
89be67 |
(int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
|
|
|
89be67 |
diff --git a/src/readelf.c b/src/readelf.c
|
|
|
89be67 |
index de016b5..1f4d1f4 100644
|
|
|
89be67 |
--- a/src/readelf.c
|
|
|
89be67 |
+++ b/src/readelf.c
|
|
|
89be67 |
@@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t);
|
|
|
89be67 |
private uint32_t getu32(int, uint32_t);
|
|
|
89be67 |
private uint64_t getu64(int, uint64_t);
|
|
|
89be67 |
|
|
|
89be67 |
+#define MAX_PHNUM 2048
|
|
|
89be67 |
+#define MAX_SHNUM 32768
|
|
|
89be67 |
+
|
|
|
89be67 |
+private int
|
|
|
89be67 |
+toomany(struct magic_set *ms, const char *name, uint16_t num)
|
|
|
89be67 |
+{
|
|
|
89be67 |
+ if (file_printf(ms, ", too many %s header sections (%u)", name, num
|
|
|
89be67 |
+ ) == -1)
|
|
|
89be67 |
+ return -1;
|
|
|
89be67 |
+ return 0;
|
|
|
89be67 |
+}
|
|
|
89be67 |
+
|
|
|
89be67 |
private uint16_t
|
|
|
89be67 |
getu16(int swap, uint16_t value)
|
|
|
89be67 |
{
|
|
|
89be67 |
@@ -388,13 +400,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
|
|
|
89be67 |
if (namesz & 0x80000000) {
|
|
|
89be67 |
(void)file_printf(ms, ", bad note name size 0x%lx",
|
|
|
89be67 |
(unsigned long)namesz);
|
|
|
89be67 |
- return offset;
|
|
|
89be67 |
+ return 0;
|
|
|
89be67 |
}
|
|
|
89be67 |
|
|
|
89be67 |
if (descsz & 0x80000000) {
|
|
|
89be67 |
(void)file_printf(ms, ", bad note description size 0x%lx",
|
|
|
89be67 |
(unsigned long)descsz);
|
|
|
89be67 |
- return offset;
|
|
|
89be67 |
+ return 0;
|
|
|
89be67 |
}
|
|
|
89be67 |
|
|
|
89be67 |
|
|
|
89be67 |
@@ -851,6 +863,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
|
|
89be67 |
Elf32_Shdr sh32;
|
|
|
89be67 |
Elf64_Shdr sh64;
|
|
|
89be67 |
int stripped = 1;
|
|
|
89be67 |
+ size_t nbadcap = 0;
|
|
|
89be67 |
void *nbuf;
|
|
|
89be67 |
off_t noff, coff, name_off;
|
|
|
89be67 |
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
|
|
|
89be67 |
@@ -928,6 +941,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
|
|
89be67 |
free(nbuf);
|
|
|
89be67 |
break;
|
|
|
89be67 |
case SHT_SUNW_cap:
|
|
|
89be67 |
+ if (nbadcap > 5)
|
|
|
89be67 |
+ break;
|
|
|
89be67 |
if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
|
|
|
89be67 |
file_badseek(ms);
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
@@ -963,6 +978,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
|
|
89be67 |
(unsigned long long)xcap_tag,
|
|
|
89be67 |
(unsigned long long)xcap_val) == -1)
|
|
|
89be67 |
return -1;
|
|
|
89be67 |
+ if (nbadcap++ > 2)
|
|
|
89be67 |
+ coff = xsh_size;
|
|
|
89be67 |
break;
|
|
|
89be67 |
}
|
|
|
89be67 |
}
|
|
|
89be67 |
@@ -1142,7 +1159,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
|
|
|
89be67 |
int flags = 0;
|
|
|
89be67 |
Elf32_Ehdr elf32hdr;
|
|
|
89be67 |
Elf64_Ehdr elf64hdr;
|
|
|
89be67 |
- uint16_t type;
|
|
|
89be67 |
+ uint16_t type, phnum, shnum;
|
|
|
89be67 |
|
|
|
89be67 |
if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
|
|
|
89be67 |
return 0;
|