summaryrefslogtreecommitdiffstats
path: root/libdwfl/link_map.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-11-22 23:08:48 +0100
committerMark Wielaard <[email protected]>2014-11-26 20:17:22 +0100
commit712c8faddc08844fb1f2814c8b6e817f03b0698e (patch)
treedf68a29bd32a009875438dfbbd68cbe6f30425c0 /libdwfl/link_map.c
parent2deeb7c51020df07d752107cdc6822d70ae1da4e (diff)
Use elf_getphdrnum instead of accessing ehdr->e_phnum directly.
Using elf_getphdrnum lets us handle ELF files that use more than PN_XNUM phdrs. And guards against some corrupt files. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdwfl/link_map.c')
-rw-r--r--libdwfl/link_map.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 272f89ba..eaf43b57 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -1,5 +1,5 @@
/* Report modules by examining dynamic linker data structures.
- Copyright (C) 2008-2013 Red Hat, Inc.
+ Copyright (C) 2008-2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -533,7 +533,11 @@ consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry,
address where &r_debug was written at runtime. */
GElf_Xword align = mod->dwfl->segment_align;
GElf_Addr d_val_vaddr = 0;
- for (uint_fast16_t i = 0; i < ehdr.e_phnum; ++i)
+ size_t phnum;
+ if (elf_getphdrnum (mod->main.elf, &phnum) != 0)
+ return 0;
+
+ for (size_t i = 0; i < phnum; ++i)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
@@ -813,7 +817,15 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
__libdwfl_seterrno (DWFL_E_LIBELF);
return false;
}
- if (ehdr->e_phnum != phnum || ehdr->e_phentsize != phent)
+ size_t e_phnum;
+ if (elf_getphdrnum (elf, &e_phnum) != 0)
+ {
+ elf_end (elf);
+ close (fd);
+ __libdwfl_seterrno (DWFL_E_LIBELF);
+ return false;
+ }
+ if (e_phnum != phnum || ehdr->e_phentsize != phent)
{
elf_end (elf);
close (fd);