diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2017-09-29 16:05:54 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2017-09-29 16:05:54 +0000 |
commit | 7cc6ab57191566aa7eebcfa932b8ae4e91725b82 (patch) | |
tree | 3370bd3ae1ff3e99f4806277066e1cae31e3a665 /usr.bin | |
parent | 045cf6eca4d1d81259e9940702434c691f76f583 (diff) |
Check that the end of sections do not exceed the filesize for both
symtab and sections. Corrects behaviour that led to crashes found
via afl.
ok mpi@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ctfconv/ctfconv.c | 6 | ||||
-rw-r--r-- | usr.bin/ctfconv/elf.c | 25 |
2 files changed, 18 insertions, 13 deletions
diff --git a/usr.bin/ctfconv/ctfconv.c b/usr.bin/ctfconv/ctfconv.c index 050b74ec8b5..06891784ed8 100644 --- a/usr.bin/ctfconv/ctfconv.c +++ b/usr.bin/ctfconv/ctfconv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ctfconv.c,v 1.11 2017/09/29 09:30:42 mpi Exp $ */ +/* $OpenBSD: ctfconv.c,v 1.12 2017/09/29 16:05:53 jsg Exp $ */ /* * Copyright (c) 2016-2017 Martin Pieuchot @@ -59,7 +59,7 @@ void dump_obj(struct itype *, int *); /* elf.c */ int iself(const char *, size_t); int elf_getshstab(const char *, size_t, const char **, size_t *); -ssize_t elf_getsymtab(const char *, const char *, size_t, +ssize_t elf_getsymtab(const char *, size_t, const char *, size_t, const Elf_Sym **, size_t *); ssize_t elf_getsection(char *, size_t, const char *, const char *, size_t, const char **, size_t *); @@ -222,7 +222,7 @@ elf_convert(char *p, size_t filesize) return 1; /* Find symbol table location and number of symbols. */ - if (elf_getsymtab(p, shstab, shstabsz, &symtab, &nsymb) == -1) + if (elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, &nsymb) == -1) warnx("symbol table not found"); /* Find string table location and size. */ diff --git a/usr.bin/ctfconv/elf.c b/usr.bin/ctfconv/elf.c index 8dba5dbe6aa..24230b26f3a 100644 --- a/usr.bin/ctfconv/elf.c +++ b/usr.bin/ctfconv/elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: elf.c,v 1.4 2017/09/26 09:40:28 jsg Exp $ */ +/* $OpenBSD: elf.c,v 1.5 2017/09/29 16:05:53 jsg Exp $ */ /* * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org> @@ -26,8 +26,8 @@ #include <string.h> static int elf_reloc_size(unsigned long); -static void elf_reloc_apply(const char *, const char *, size_t, ssize_t, - char *, size_t); +static void elf_reloc_apply(const char *, size_t, const char *, size_t, + ssize_t, char *, size_t); int iself(const char *p, size_t filesize) @@ -103,8 +103,8 @@ elf_getshstab(const char *p, size_t filesize, const char **shstab, } ssize_t -elf_getsymtab(const char *p, const char *shstab, size_t shstabsz, - const Elf_Sym **symtab, size_t *nsymb) +elf_getsymtab(const char *p, size_t filesize, const char *shstab, + size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb) { Elf_Ehdr *eh = (Elf_Ehdr *)p; Elf_Shdr *sh; @@ -122,6 +122,9 @@ elf_getsymtab(const char *p, const char *shstab, size_t shstabsz, if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) continue; + if ((sh->sh_offset + sh->sh_size) > filesize) + continue; + if (strncmp(shstab + sh->sh_name, ELF_SYMTAB, snlen) == 0) { if (symtab != NULL) *symtab = (Elf_Sym *)(p + sh->sh_offset); @@ -156,14 +159,15 @@ elf_getsection(char *p, size_t filesize, const char *sname, const char *shstab, if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) continue; - if (sh->sh_offset >= filesize) + if ((sh->sh_offset + sh->sh_size) > filesize) continue; if (strncmp(shstab + sh->sh_name, sname, snlen) == 0) { sidx = i; sdata = p + sh->sh_offset; ssz = sh->sh_size; - elf_reloc_apply(p, shstab, shstabsz, sidx, sdata, ssz); + elf_reloc_apply(p, filesize, shstab, shstabsz, sidx, + sdata, ssz); break; } } @@ -214,8 +218,8 @@ do { \ } while (0) static void -elf_reloc_apply(const char *p, const char *shstab, size_t shstabsz, - ssize_t sidx, char *sdata, size_t ssz) +elf_reloc_apply(const char *p, size_t filesize, const char *shstab, + size_t shstabsz, ssize_t sidx, char *sdata, size_t ssz) { Elf_Ehdr *eh = (Elf_Ehdr *)p; Elf_Shdr *sh; @@ -229,7 +233,8 @@ elf_reloc_apply(const char *p, const char *shstab, size_t shstabsz, int rsize; /* Find symbol table location and number of symbols. */ - symtabidx = elf_getsymtab(p, shstab, shstabsz, &symtab, &nsymb); + symtabidx = elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, + &nsymb); if (symtabidx == -1) { warnx("symbol table not found"); return; |