Skip to content

Commit

Permalink
Fix bug in walking .gnu.version_r linked list
Browse files Browse the repository at this point in the history
When writing the code to teach --replace-needed to modify the
.gnu.version_r section (NixOSgh-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.
  • Loading branch information
njsmith committed Apr 2, 2016
1 parent 77efcf2 commit abae785
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion src/patchelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit abae785

Please sign in to comment.