summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-10-14 16:58:51 +0200
committerMark Wielaard <mark@klomp.org>2018-10-20 00:13:09 +0200
commit577511f66842c324c811d1530eea32792f2bee29 (patch)
tree129644b6fe00b5ed708278b49e5aaee36476d9ac
parent20f9de9b5f704cec55df92406a50bcbcfca96acd (diff)
findtextrel: Check that sh_entsize isn't zero.
A bogus ELF file could have sh_entsize as zero. Don't divide by zero, but just assume there are no entries in the section. https://sourceware.org/bugzilla/show_bug.cgi?id=23755 Signed-off-by: Mark Wielaard <mark@klomp.org>
-rw-r--r--src/ChangeLog4
-rw-r--r--src/findtextrel.c23
2 files changed, 17 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 680291be..d057669c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-14 Mark Wielaard <mark@klomp.org>
+
+ * findtextrel.c (process_file): Check that sh_entsize is not zero.
+
2018-09-13 Mark Wielaard <mark@klomp.org>
* readelf.c (print_debug_macro_section): Use elf_getdata. Print
diff --git a/src/findtextrel.c b/src/findtextrel.c
index 49731592..f48752e5 100644
--- a/src/findtextrel.c
+++ b/src/findtextrel.c
@@ -1,5 +1,5 @@
/* Locate source files or functions which caused text relocations.
- Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc.
+ Copyright (C) 2005-2010, 2012, 2014, 2018 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
@@ -263,9 +263,10 @@ process_file (const char *fname, bool more_than_one)
seen_dynamic = true;
Elf_Data *data = elf_getdata (scn, NULL);
+ size_t entries = (shdr->sh_entsize == 0
+ ? 0 : shdr->sh_size / shdr->sh_entsize);
- for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize;
- ++cnt)
+ for (size_t cnt = 0; cnt < entries; ++cnt)
{
GElf_Dyn dynmem;
GElf_Dyn *dyn;
@@ -413,10 +414,11 @@ cannot get symbol table section %zu in '%s': %s"),
if (shdr->sh_type == SHT_REL)
{
Elf_Data *data = elf_getdata (scn, NULL);
+ size_t entries = (shdr->sh_entsize == 0
+ ? 0 : shdr->sh_size / shdr->sh_entsize);
for (int cnt = 0;
- (size_t) cnt < shdr->sh_size / shdr->sh_entsize;
- ++cnt)
+ (size_t) cnt < entries; ++cnt)
{
GElf_Rel rel_mem;
GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
@@ -436,10 +438,10 @@ cannot get relocation at index %d in section %zu in '%s': %s"),
else if (shdr->sh_type == SHT_RELA)
{
Elf_Data *data = elf_getdata (scn, NULL);
+ size_t entries = (shdr->sh_entsize == 0
+ ? 0 : shdr->sh_size / shdr->sh_entsize);
- for (int cnt = 0;
- (size_t) cnt < shdr->sh_size / shdr->sh_entsize;
- ++cnt)
+ for (int cnt = 0; (size_t) cnt < entries; ++cnt)
{
GElf_Rela rela_mem;
GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
@@ -531,9 +533,10 @@ check_rel (size_t nsegments, struct segments segments[nsegments],
int highidx = -1;
GElf_Sym sym_mem;
GElf_Sym *sym;
+ size_t entries = (shdr->sh_entsize == 0
+ ? 0 : shdr->sh_size / shdr->sh_entsize);
- for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize;
- ++i)
+ for (int i = 0; (size_t) i < entries; ++i)
{
sym = gelf_getsym (symdata, i, &sym_mem);
if (sym == NULL)