diff options
author | Mike Frysinger <vapier@gentoo.org> | 2017-01-23 16:13:03 -1000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2017-01-23 16:13:03 -1000 |
commit | 82fc8ce64f61445c52e5c9a4d5ac294b6af7c92d (patch) | |
tree | 62c4343acd5555c5a16cf757b654d42ca8760b41 | |
parent | scanelf: change abs() to a size_t cast (diff) | |
download | pax-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.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -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) \ |