diff options
author | Nathaniel J. Smith <njs@pobox.com> | 2016-04-02 20:07:57 (GMT) |
---|---|---|
committer | Nathaniel J. Smith <njs@pobox.com> | 2016-04-02 20:12:04 (GMT) |
commit | abae7858d6552cf76649fa521e777ac6aa557763 (patch) | |
tree | 964ab306ba385618ae2f10f67143aa5e7211bf70 | |
parent | 77efcf2f2d2f95391a6717cc9457f87267500e72 (diff) | |
download | patchelf-abae7858d6552cf76649fa521e777ac6aa557763.zip patchelf-abae7858d6552cf76649fa521e777ac6aa557763.tar.gz patchelf-abae7858d6552cf76649fa521e777ac6aa557763.tar.bz2 |
Fix bug in walking .gnu.version_r linked list
When writing the code to teach --replace-needed to modify the
.gnu.version_r section (gh-85), I misunderstood how the ->vn_next
pointers in the Elf_Verneed structs are supposed to be interpreted: I
thought they gave an offset from the beginning of the section, but in
fact they give an offset relative to the current struct. The resulting
bug was very odd: generally, patchelf would complete without signalling
an error, but it would only successfully replace filenames that occurred
as either the first or second entries in the .gnu.version_r section,
while the third or later entries would be left untouched.
This commit fixes the interpretation of the ->vn_next pointers, so that
now --replace-needed should work correctly even on ELF files with more
than two version needed structs.
Thanks to @matthew-brett for finding the bug / providing a test case,
and to @rmcgibbo for helping me diagnose it.
-rw-r--r-- | src/patchelf.cc | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc index 91abc6e..6c53e85 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -1337,7 +1337,7 @@ void ElfFile<ElfFileParamNames>::replaceNeeded(map<string, string>& libs) debug("keeping .gnu.version_r entry `%s'\n", file); } // the Elf_Verneed structures form a linked list, so jump to next entry - need = (Elf_Verneed *) (contents + rdi(shdrVersionR.sh_offset) + rdi(need->vn_next)); + need = (Elf_Verneed *) (((char *) need) + rdi(need->vn_next)); --verNeedNum; } } |