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