aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2017-01-23 16:13:03 -1000
committerMike Frysinger <vapier@gentoo.org>2017-01-23 16:13:03 -1000
commit82fc8ce64f61445c52e5c9a4d5ac294b6af7c92d (patch)
tree62c4343acd5555c5a16cf757b654d42ca8760b41
parentscanelf: change abs() to a size_t cast (diff)
downloadpax-utils-82fc8ce64f61445c52e5c9a4d5ac294b6af7c92d.tar.gz
pax-utils-82fc8ce64f61445c52e5c9a4d5ac294b6af7c92d.tar.bz2
pax-utils-82fc8ce64f61445c52e5c9a4d5ac294b6af7c92d.zip
scanelf: fix offset checking when looking up symbols via hash
A number of refactors hid bugs here in that the first offset value here would be left over from earlier code. Localize the code a bit to try and keep that from happening again. We also reload phdr since this loop expects to walk the whole table.
-rw-r--r--scanelf.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/scanelf.c b/scanelf.c
index 2729d0f..52c436a 100644
--- a/scanelf.c
+++ b/scanelf.c
@@ -261,7 +261,7 @@ static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **str)
Elf ## B ## _Phdr *phdr; \
Elf ## B ## _Addr vsym, vstr, vhash, vgnu_hash; \
Elf ## B ## _Dyn *dyn; \
- Elf ## B ## _Off offset; \
+ Elf ## B ## _Off doffset; \
\
/* lookup symbols used at runtime with DT_SYMTAB / DT_STRTAB */ \
vsym = vstr = vhash = vgnu_hash = 0; \
@@ -272,9 +272,9 @@ static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **str)
phdr = scanelf_file_get_pt_dynamic(elf); \
if (phdr == NULL) \
break; \
- offset = EGET(phdr->p_offset); \
+ doffset = EGET(phdr->p_offset); \
\
- dyn = DYN ## B (elf->vdata + offset); \
+ dyn = DYN ## B (elf->vdata + doffset); \
while (EGET(dyn->d_tag) != DT_NULL) { \
switch (EGET(dyn->d_tag)) { \
case DT_SYMTAB: vsym = EGET(dyn->d_un.d_val); break; \
@@ -290,15 +290,16 @@ static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **str)
return; \
\
/* calc offset into the ELF by finding the load addr of the syms */ \
+ phdr = PHDR ## B (elf->phdr); \
for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
Elf ## B ## _Addr vaddr = EGET(phdr[i].p_vaddr); \
Elf ## B ## _Addr filesz = EGET(phdr[i].p_filesz); \
+ Elf ## B ## _Off offset = EGET(phdr[i].p_offset); \
Elf ## B ## _Off hash_offset = offset + (vhash - vaddr); \
\
if (EGET(phdr[i].p_type) != PT_LOAD) \
continue; \
\
- offset = EGET(phdr[i].p_offset); \
if (offset >= (uint64_t)elf->len) \
goto corrupt_hash; \
if (filesz >= (uint64_t)elf->len) \