-
-
Notifications
You must be signed in to change notification settings - Fork 643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Library corruption when setting RPATH #466
Comments
I acknowledge this issue and it seems that the crash appends in a ELF destructor of |
I guess that the problem is that the address of that deallocator is not correct after LIEF writes the new elf because the program counter there is not reflected in the DWARF information. The address is also absent from the .eh_frame section |
Well actually it seems that they are two pointers at the beginning of the |
Unfortunately no, but I can tell you that it comes from the system libraries in RHEL6.8 system. There are some particularities that I noticed, one of the clear ones is that the value of the offset and the address in the section headers is not equal (which is totally valid but uncommon). |
Yes I also noticed that it uses |
If think I found the fix! I still need to check some things but it should be pushed in the next couple of days. |
Fantastic! I am curious, where did the problem reside in LIEF? |
From what I understood, the beginning of the
Which is implemented in the linker as follows: // dl-machine.h from glibc 2.32
static inline int
elf_machine_runtime_setup (struct link_map *l, int lazy)
{
extern void _dl_runtime_resolve (Elf32_Word);
if (lazy)
{
/* The GOT entries for functions in the PLT have not yet been filled
in. Their initial contents will arrange when called to push an
offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
and then jump to _GLOBAL_OFFSET_TABLE[2]. */
Elf32_Addr *got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
got[1] = (Elf32_Addr) l; /* Identify this shared object. */
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
}
return lazy;
}
...
/* If a library is prelinked but we have to relocate anyway,
we have to be able to undo the prelinking of .got.plt.
The prelinker saved us here address of .plt + 0x16.
*/
if (got[1]) {
l->l_mach.plt = got[1] + l->l_addr;
l->l_mach.gotplt = (ElfW(Addr)) &got[3];
} In the case of Reference: https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf |
@pablogsal I'm waiting for the CI but the fix is here: c4a44d5#diff-c0ab473ba9cb221f36850d63e9f329c6R702 |
See: 1a416ea |
Thank you very much @romainthomas ! |
Describe the bug
Some shared libraries are corrupted when lief sets the RPATH to some new value.
To Reproduce
Consider this shared library:
https://www.dropbox.com/s/n47wla3tgw4ny56/libfreebl3.so?dl=0
If you create a very simple executable that links against it, everything works:
but now, changing the RPATH makes the program segfault:
Running the program now segfaults:
Apparently, the segfault happens when the linker is calling the deallocator for the library:
Expected behavior
The library is not corrupted and running the previous example works correctly without segfaulting.
Environment (please complete the following information):
The text was updated successfully, but these errors were encountered: