summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2017-09-29 16:05:54 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2017-09-29 16:05:54 +0000
commit7cc6ab57191566aa7eebcfa932b8ae4e91725b82 (patch)
tree3370bd3ae1ff3e99f4806277066e1cae31e3a665 /usr.bin
parent045cf6eca4d1d81259e9940702434c691f76f583 (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.c6
-rw-r--r--usr.bin/ctfconv/elf.c25
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;