aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2015-02-28 22:57:40 +0000
committerMike Frysinger <vapier@gentoo.org>2015-02-28 22:57:40 +0000
commit480966da3e22c65ca0174e9384c17f4a4cc30f32 (patch)
tree8a1a7a04bf0423271ada96b139779044c1b866ef
parentadd a fuzz target (diff)
downloadpax-utils-480966da3e22c65ca0174e9384c17f4a4cc30f32.tar.gz
pax-utils-480966da3e22c65ca0174e9384c17f4a4cc30f32.tar.bz2
pax-utils-480966da3e22c65ca0174e9384c17f4a4cc30f32.zip
scanelf: check shdrs are valid before using them
-rw-r--r--paxelf.h9
-rw-r--r--scanelf.c14
2 files changed, 16 insertions, 7 deletions
diff --git a/paxelf.h b/paxelf.h
index a83f208..1c1d672 100644
--- a/paxelf.h
+++ b/paxelf.h
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2012 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/pax-utils/paxelf.h,v 1.60 2014/06/18 03:16:52 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/pax-utils/paxelf.h,v 1.61 2015/02/28 22:57:40 vapier Exp $
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
@@ -40,6 +40,13 @@ typedef struct {
#define SYM32(ptr) ((Elf32_Sym *)(ptr))
#define SYM64(ptr) ((Elf64_Sym *)(ptr))
+#define VALID_SHDR(elf, shdr) \
+ (shdr && \
+ EGET(shdr->sh_type) != SHT_NOBITS && \
+ EGET(shdr->sh_offset) < (uint64_t)elf->len && \
+ EGET(shdr->sh_size) < (uint64_t)elf->len && \
+ EGET(shdr->sh_offset) < elf->len - EGET(shdr->sh_size))
+
/* prototypes */
extern char *pax_short_hf_flags(unsigned long flags);
extern char *pax_short_pf_flags(unsigned long flags);
diff --git a/scanelf.c b/scanelf.c
index 4bc274b..2cbe4ca 100644
--- a/scanelf.c
+++ b/scanelf.c
@@ -1,13 +1,13 @@
/*
* Copyright 2003-2012 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.275 2015/02/24 06:58:39 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.276 2015/02/28 22:57:40 vapier Exp $
*
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
* Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
*/
-static const char rcsid[] = "$Id: scanelf.c,v 1.275 2015/02/24 06:58:39 vapier Exp $";
+static const char rcsid[] = "$Id: scanelf.c,v 1.276 2015/02/28 22:57:40 vapier Exp $";
const char argv0[] = "scanelf";
#include "paxinc.h"
@@ -189,13 +189,13 @@ static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **str)
Elf ## B ## _Shdr *edynsym = dynsym; \
Elf ## B ## _Shdr *edynstr = dynstr; \
\
- if (symtab && EGET(esymtab->sh_type) == SHT_NOBITS) \
+ if (!VALID_SHDR(elf, esymtab)) \
symtab = NULL; \
- if (dynsym && EGET(edynsym->sh_type) == SHT_NOBITS) \
+ if (!VALID_SHDR(elf, edynsym)) \
dynsym = NULL; \
- if (strtab && EGET(estrtab->sh_type) == SHT_NOBITS) \
+ if (!VALID_SHDR(elf, estrtab)) \
strtab = NULL; \
- if (dynstr && EGET(edynstr->sh_type) == SHT_NOBITS) \
+ if (!VALID_SHDR(elf, edynstr)) \
dynstr = NULL; \
\
/* Use the set with more symbols if both exist. */ \
@@ -1404,6 +1404,8 @@ static const char *scanelf_file_sym(elfobj *elf, char *found_sym)
Elf ## B ## _Word i, cnt = EGET(symtab->sh_entsize); \
char *symname; \
size_t ret_len = 0; \
+ if (!VALID_SHDR(elf, symtab) || !VALID_SHDR(elf, strtab)) \
+ goto break_out; \
if (cnt) \
cnt = EGET(symtab->sh_size) / cnt; \
for (i = 0; i < cnt; ++i) { \