Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LD_PRELOAD mixed 64bit/32bit environment in Linux

I would like to set LD_PRELOAD to point to a shared library where I might run either a 64bit or 32bit application. It is obvious that the shared library and the executable have to match in bit-ness.

$ LD_PRELOAD=/lib64/lib_init.so ./hello32
ERROR: ld.so: object '/lib64/lib_init.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS64): ignored

where hello32 is a 32 bit application. There are some pages out in the world that say that I should be able to do:

$ LD_PRELOAD='/$LIB/lib_init.so' ./hello32
ERROR: ld.so: object '/$LIB/lib_init.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored

Where $LIB will automatically switch between lib and lib64 depending on whether the application is 32 or 64bit. But obviously this doesn't work.

Is there some trick to make this work? LD_PRELOAD_32, LD_PRELOAD_64? Thanks!

like image 788
Robert McLay Avatar asked Apr 25 '16 19:04

Robert McLay


2 Answers

By specifying full path to the library, you don't let dynamic linker to adjust it's search path according to binaries architecture. Define only library name and let linker to pick the correct library for you. E.g.:

$ LD_PRELOAD=lib_init.so ./hello32

will search for lib_init.so in /lib, while

$ LD_PRELOAD=lib_init.so ./hello64

will search in /lib64

like image 86
kofemann Avatar answered Nov 11 '22 06:11

kofemann


It turns out that you can set use $LIB when setting LD_PRELOAD (or setting the file /etc/ld.so.preload). The trouble is that the value that $LIB gets set to depends on your linux distribution. UGH!

In my limited testing, I have discovered that Redhat based systems have $LIB expand to "lib64" for 64 bit applications and "lib" for 32 bit applications.

However, on debian based distributions I have discovered that $LIB expands to "lib/x86_64-linux-gnu" for 64 bit applications and "lib/i386-linux-gnu" for 32 bit applications. I haven't been able to find any documentation on this but I have tested this.

This means that if I have:

 $ LD_PRELOAD='/$LIB/lib_init.so'  ./hello64

and on a debian based system like ubuntu I have:

/lib/x86_64-linux-gnu/lib_init.so  (for 64bit apps)

and

/lib/i386-linux-gnu/lib_init.so  (for 32bit apps)

This will work fine (on a ubuntu based linux computer)

Otherwise on a redhat based distribution you need

  /lib64/lib_init.so and /lib/lib_init.so

for 64 and 32 bit apps.

Using LD_PRELOAD='/$LIB/lib_init.so' has an advantage that you are not dependent the value of $LD_LIBRARY_PATH.

Just do not forget the single quotes when setting $LIB in LD_PRELOAD

like image 30
user2410881 Avatar answered Nov 11 '22 04:11

user2410881