=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ctfconv/elf.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/ctfconv/elf.c 2017/11/06 14:59:27 1.8 +++ src/usr.bin/ctfconv/elf.c 2017/11/14 09:14:50 1.9 @@ -1,4 +1,4 @@ -/* $OpenBSD: elf.c,v 1.8 2017/11/06 14:59:27 mpi Exp $ */ +/* $OpenBSD: elf.c,v 1.9 2017/11/14 09:14:50 mpi Exp $ */ /* * Copyright (c) 2016 Martin Pieuchot @@ -80,8 +80,15 @@ { Elf_Ehdr *eh = (Elf_Ehdr *)p; Elf_Shdr *sh; + size_t shoff; - sh = (Elf_Shdr *)(p + eh->e_shoff + eh->e_shstrndx * eh->e_shentsize); + shoff = eh->e_shoff + eh->e_shstrndx * eh->e_shentsize; + if (shoff > (filesize - sizeof(*sh))) { + warnx("unexpected string table size"); + return -1; + } + + sh = (Elf_Shdr *)(p + shoff); if (sh->sh_type != SHT_STRTAB) { warnx("unexpected string table type"); return -1; @@ -109,24 +116,30 @@ { Elf_Ehdr *eh = (Elf_Ehdr *)p; Elf_Shdr *sh, *symsh; - size_t snlen; + size_t snlen, shoff; ssize_t i; snlen = strlen(ELF_SYMTAB); symsh = NULL; for (i = 0; i < eh->e_shnum; i++) { - sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize); + shoff = eh->e_shoff + i * eh->e_shentsize; + if (shoff > (filesize - sizeof(*sh))) + continue; + sh = (Elf_Shdr *)(p + shoff); if (sh->sh_type != SHT_SYMTAB) continue; if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) continue; - if ((sh->sh_offset + sh->sh_size) > filesize) + if (sh->sh_offset > filesize) continue; + if (sh->sh_size > (filesize - sh->sh_offset)) + continue; + if (sh->sh_entsize == 0) continue; @@ -144,8 +157,11 @@ if (symsh == NULL || (symsh->sh_link >= eh->e_shnum)) return -1; - sh = (Elf_Shdr *)(p + eh->e_shoff + symsh->sh_link * eh->e_shentsize); + shoff = eh->e_shoff + symsh->sh_link * eh->e_shentsize; + if (shoff > (filesize - sizeof(*sh))) + return -1; + sh = (Elf_Shdr *)(p + shoff); if ((sh->sh_offset + sh->sh_size) > filesize) return -1; @@ -164,7 +180,7 @@ Elf_Ehdr *eh = (Elf_Ehdr *)p; Elf_Shdr *sh; char *sdata = NULL; - size_t snlen, ssz = 0; + size_t snlen, shoff, ssz = 0; ssize_t sidx, i; snlen = strlen(sname); @@ -173,17 +189,20 @@ /* Find the given section. */ for (i = 0; i < eh->e_shnum; i++) { - if ((eh->e_shoff + i * eh->e_shentsize) > filesize) + shoff = eh->e_shoff + i * eh->e_shentsize; + if (shoff > (filesize - sizeof(*sh))) continue; - sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize); - + sh = (Elf_Shdr *)(p + shoff); if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) continue; - if ((sh->sh_offset + sh->sh_size) > filesize) + if (sh->sh_offset > filesize) continue; + if (sh->sh_size > (filesize - sh->sh_offset)) + continue; + if (strncmp(shstab + sh->sh_name, sname, snlen) == 0) { sidx = i; sdata = p + sh->sh_offset; @@ -250,7 +269,7 @@ const Elf_Sym *symtab, *sym; ssize_t symtabidx; size_t nsymb, rsym, rtyp, roff; - size_t i, j; + size_t shoff, i, j; uint64_t value; int rsize; @@ -264,18 +283,21 @@ /* Apply possible relocation. */ for (i = 0; i < eh->e_shnum; i++) { - if ((eh->e_shoff + i * eh->e_shentsize) > filesize) + shoff = eh->e_shoff + i * eh->e_shentsize; + if (shoff > (filesize - sizeof(*sh))) continue; - sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize); - + sh = (Elf_Shdr *)(p + shoff); if (sh->sh_size == 0) continue; if ((sh->sh_info != sidx) || (sh->sh_link != symtabidx)) continue; - if ((sh->sh_offset + sh->sh_size) > filesize) + if (sh->sh_offset > filesize) + continue; + + if (sh->sh_size > (filesize - sh->sh_offset)) continue; switch (sh->sh_type) {