I need to make ELF binary file to use another version of libc.so for scientific purposes. I tried to do it with LD_PRELOAD and patchelf utility, but then binary does not run with an errors like:
./a.out: error while loading shared libraries: libc-2.15.so: cannot open shared object file: No such file or directory or Segmentation fault (core dumped).
I think that it is because I need another version of ld.so.
What is most efficient way to make binary use my version of libc?
EDIT: I do not have source code of binary.
EDIT: Error message edited. No SELinux, no AppArmor.
For me it looks that you did not spend the whole path to the new libc variant.
I did the following:
ldd example
linux-vdso.so.1 (0x00007ffe9c087000)
libstdc++.so.6 => /opt/linux-gnu_6.1.0/lib64/libstdc++.so.6 (0x00007f0cef872000)
libm.so.6 => /lib64/libm.so.6 (0x00007f0cef56f000)
libgcc_s.so.1 => /opt/linux-gnu_6.1.0/lib64/libgcc_s.so.1 (0x00007f0cef359000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0ceef98000)
/lib64/ld-linux-x86-64.so.2 (0x000055ca3cb92000)
LD_PRELOAD=/tmp/bug_libc.so ldd example
linux-vdso.so.1 (0x00007ffc2cff8000)
/tmp/bug_libc.so (0x00007f56a1358000)
libstdc++.so.6 => /opt/linux-gnu_6.1.0/lib64/libstdc++.so.6 (0x00007f56a0f9a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f56a0c98000)
libgcc_s.so.1 => /opt/linux-gnu_6.1.0/lib64/libgcc_s.so.1 (0x00007f56a0a82000)
/lib64/ld-linux-x86-64.so.2 (0x00005605c8a7a000)
If I replace with a non valid libc a got a different error message. Only if I gave the wrong path like:
LD_PRELOAD=/tmp/bug_libc.so2 ldd go
ERROR: ld.so: object '/tmp/bug_libc.so2' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/tmp/bug_libc.so2' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
linux-vdso.so.1 (0x00007ffedcde4000)
libstdc++.so.6 => /opt/linux-gnu_6.1.0/lib64/libstdc++.so.6 (0x00007f3ae2188000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3ae1e85000)
libgcc_s.so.1 => /opt/linux-gnu_6.1.0/lib64/libgcc_s.so.1 (0x00007f3ae1c6f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3ae18ae000)
/lib64/ld-linux-x86-64.so.2 (0x000055df54aae000)
Maybe you have some other problem by accessing your replacement libc-file. Check the access flags on the file and also check if SELinux or AppArmor or other protection stops loading libc in your environment. Because replacing libc opens a security hole it is a candidate for SELinux & Co!
And you should check always with ldd first. Maybe your new libc requires some more (older) variants of other libs which can not be found on your system. Normaly libc did not require other libs, but I have no idea what game you are playing. Whatever: ldd gives you a more detailed answer to the things which are going on in the library loading phase.
EDIT: segfault
If you get segfault, you typically have compiled your application with incompatible header files. You have to compile with the headers which comes with the libc version you want to use. If you compile against your system headers for system libc and run any incompatible version of precompiled libc, you get any kind of memory errors by accessing wrong data structures.
This answer explains why LD_PRELOAD can not work, and suggests solutions.
I tried to do it with LD_PRELOAD and patchelf utility
It's not clear whether your use of patchelf touched only DT_RPATH, only PT_INTERP, or both. You need to do both.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With