What is the LD_PRELOAD trick?
Asked Answered
F

9

461

I came across a reference to it recently on proggit and (as of now) it is not explained.

I suspect this might be it, but I don't know for sure.

Fetishism answered 8/1, 2009 at 22:14 Comment(1)
Not really an answer so I won't post it as one but... Stephen Kell is using LD_PRELOAD for his liballocs library in this video and if you watch the previous bits you may get a better understanding of how/why. liballocs appears to be being used so other dynamic languages can talk to each other. This talk has some deep internals explained in it. youtu.be/LwicN2u6Dro?t=24m10sAdmiralty
C
552

If you set LD_PRELOAD to the path of a shared object, that file will be loaded before any other library (including the C runtime, libc.so). So to run ls with your special malloc() implementation, do this:

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
Corbitt answered 8/1, 2009 at 22:20 Comment(12)
I had no idea this existed... it seems like it would be a major vector for security attacks. Any idea how it is secured?Oby
It is secured by the fact the loader will ignore LD_PRELOAD if ruid != euid -- JoshuaBurma
@Joshua: what are ruid and euid?Zohar
@Zohar Real and effective user ids: lst.de/~okir/blackhats/node23.htmlGanesha
Necropost: @Burma any advice how to disable the security setting? Currently working on a CTF. And I want them to use a specific exploit on sudo ( CVE: 2012-0809 ).Caxton
One important thing to keep in mind: you usually want to specify an absolute path to LD_PRELOAD. The reason is that it being an environment variable, it's inherited by child processes - which may have a different working directory than the parent process. So any relative path would fail to locate the library to preload.Procephalic
lst.de/ link is 403 access forbidden, here is web.archive.org/web/20080318213813/http://www.lst.de/~okir/…Admiralty
@SathOkh: # touch /etc/shadow ... touch: cannot touch '/etc/shadow': Permission denied ... # whoami ... root ... # ps -u -p $$ | tail -n 1 | cut -d ' ' -f 1 ... keithb ...Cerebellum
@SathOkh lcamtuf's exploit is a joke. It pretends its *uid are zero but they are not really.Cabalist
Nvm, my mistake :(Gotten
One neat LD_PRELOAD application is stderred, which causes anything written to stderr to be colored red in the terminal.Glynas
See also this tutorial for how to build the *.so shared object: cprogramming.com/tutorial/shared-libraries-linux-gcc.html.Mcreynolds
B
70

You can override symbols in the stock libraries by creating a library with the same symbols and specifying the library in LD_PRELOAD.

Some people use it to specify libraries in nonstandard locations, but LD_LIBRARY_PATH is better for that purpose.

Burma answered 8/1, 2009 at 22:18 Comment(6)
"Some people use it to specify libraries in nonstandard locations"... Really? Sounds like "Some people use it wrong"!Jennefer
LD_PRELOAD can by virtue of load order intercept application-specified hardcoded paths.Burma
Would it be a misuse to preload a different version of a library - assuming they are compatible?Cassycast
I've seen it used to load a debug or instrumented variant, or to load a library that does something completely radically different from the base library as though to emulate some other system.Burma
In the case where libraries aren't compiled correctly (used to run into this with mysql all the time where it had a loose coupling to a generic libmysql_client which overwrote an older version's symlink - depending on which version of perl you used you had to specify / force it with LD_PRELOAD.. useful trick. If I remember correctly, valgrind uses this technique to provide debugging ability to binaries without needing to recompile.. it's quite useful.Ferraro
@z0r: It's not a misuse if you're subject to the whims of a bad system administrator and can't install things yourself. :pFerraro
H
61

As many people mentioned, using LD_PRELOAD to preload library. By the way, you can CHECK if the setting is available by ldd command.

Example: Suppose you need to preload your own libselinux.so.1.

> ldd /bin/ls
    ...
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f3927b1d000)
    libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f3927914000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f392754f000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3927311000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f392710c000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3927d65000)
    libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f3926f07000)

Thus, set your preload environment:

export LD_PRELOAD=/home/patric/libselinux.so.1

Check your library again:

>ldd /bin/ls
    ...
    libselinux.so.1 =>
    /home/patric/libselinux.so.1 (0x00007fb9245d8000)
    ...
Hostility answered 9/12, 2015 at 6:20 Comment(0)
S
51

With LD_PRELOAD you can give libraries precedence.

For example you can write a library which implement malloc and free. And by loading these with LD_PRELOAD your malloc and free will be executed rather than the standard ones.

Stays answered 8/1, 2009 at 22:19 Comment(4)
but what if the program uses calloc? wouldn't that mess up everything?Clavate
@JanusTroelsen if the library you write doesn't implement a certain part, that part would be loaded from the original library.Xenophobia
@JanusTroelsen, In other words, LD_PRELOAD allows you to specify which implementation of a specific symbol gets used. If the preloaded library does not export a symbol, it will be found elsehwere.Donaugh
@JanusTroelsen: It turns out that malloc and free are specifically designed in glibc to allow this and the stock calloc manages to call your imported malloc. Don't try this with any other functions. It won't work so good.Burma
W
12

LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. These are implemented by the loader /lib/ld-linux.so. If you want to override just a few selected functions, you can do this by creating an overriding object file and setting LD_PRELOAD; the functions in this object file will override just those functions leaving others as they were.

For more information on shared libraries visit http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Wolenik answered 24/7, 2012 at 9:41 Comment(0)
C
8

To export mylib.so to env:

$ export LD_PRELOAD=/path/mylib.so
$ ./mybin

To disable it:

$ unset LD_PRELOAD
Cuneo answered 4/2, 2014 at 10:3 Comment(2)
or unset LD_PRELOADJesus
unset and export VAR= aren't exactly the same thing. unset is the way to go.Griff
B
4

Here is a detailed blog post about preloading:

https://blog.cryptomilk.org/2014/07/21/what-is-preloading/

Badlands answered 11/8, 2014 at 10:11 Comment(1)
Thanks for posting your answer! Please note that you should post the essential parts of the answer here, on this site, or your post risks being deleted See the FAQ where it mentions answers that are 'barely more than a link'. You may still include the link if you wish, but only as a 'reference'. The answer should stand on its own without needing the link.Mowery
U
3

When LD_PRELOAD is used, that file will be loaded before any other. Use $export LD_PRELOAD=/path/lib for lib to be pre-loaded. This can even be used in programs too.

Unpin answered 30/1, 2019 at 16:29 Comment(0)
Z
2

Using LD_PRELOAD path, you can force the application loader to load provided shared object, over the default provided.

Developers uses this to debug their applications by providing different versions of the shared objects.

We've used it to hack certain applications, by overriding existing functions using prepared shared objects.

Zeller answered 31/5, 2015 at 3:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.