From: David Rhodus Date: Mon, 29 Mar 2004 17:17:09 +0000 (+0000) Subject: Make sure the ELF header size is not too large. This fixes a potential over X-Git-Tag: v2.0.1~11646 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/2cc7c57968b2555a2197308b3a55ecd6b4ddb555 Make sure the ELF header size is not too large. This fixes a potential over flow that could happen in a number of places. In DragonFly we rely that the ELF header will be in the first page. Though the ABI specification does not require this it is always true in practice. Glanced at FreeBSD but found it be incomplete. Possibly more bounds checking is needed for other things here, though futher investigation is needed first. --- diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index a5352c4a17..c4e687b8a9 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -27,7 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/kern/imgact_elf.c,v 1.73.2.13 2002/12/28 19:49:41 dillon Exp $ - * $DragonFly: src/sys/kern/imgact_elf.c,v 1.17 2004/03/01 06:33:16 dillon Exp $ + * $DragonFly: src/sys/kern/imgact_elf.c,v 1.18 2004/03/29 17:17:09 drhodus Exp $ */ #include @@ -174,15 +174,15 @@ elf_check_header(const Elf_Ehdr *hdr) if (!IS_ELF(*hdr) || hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || hdr->e_ident[EI_DATA] != ELF_TARG_DATA || - hdr->e_ident[EI_VERSION] != EV_CURRENT) + hdr->e_ident[EI_VERSION] != EV_CURRENT || + hdr->e_phentsize != sizeof(Elf_Phdr) || + hdr->e_ehsize != sizeof(Elf_Ehdr) || + hdr->e_version != ELF_TARG_VER) return ENOEXEC; if (!ELF_MACHINE_OK(hdr->e_machine)) return ENOEXEC; - if (hdr->e_version != ELF_TARG_VER) - return ENOEXEC; - return 0; } @@ -414,9 +414,10 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) goto fail; } - /* Only support headers that fit within first page for now */ + /* Only support headers that fit within first page for now + * (multiplication of two Elf_Half fields will not overflow) */ if ((hdr->e_phoff > PAGE_SIZE) || - (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) { + (hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE - hdr->e_phoff) { error = ENOEXEC; goto fail; }