File 0001-limit-the-number-of-program-and-section-header-numbe.patch of Package file.278
From b4c01141e5367f247b84dcaf6aefbb4e741842b8 Mon Sep 17 00:00:00 2001
From: Christos Zoulas <christos@zoulas.com>
Date: Sat, 22 Nov 2014 16:04:29 +0000
Subject: [PATCH] - 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.
---
src/elfclass.h | 24 ++++++++++++++++--------
src/readelf.c | 20 ++++++++++++++++----
2 files changed, 32 insertions(+), 12 deletions(-)
diff --git src/elfclass.h src/elfclass.h
index 010958a..0826ce3 100644
--- src/elfclass.h
+++ 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 src/readelf.c src/readelf.c
index 9ebdebd..dd4672b 100644
--- src/readelf.c
+++ 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)
{
@@ -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;
--
1.7.9.2