452

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.

Community
  • 1
  • 1
Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • 3
    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. https://youtu.be/LwicN2u6Dro?t=24m10s – Elijah Lynn Feb 29 '16 at 12:30

9 Answers9

541

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
user
  • 5,335
  • 7
  • 47
  • 63
JesperE
  • 63,317
  • 21
  • 138
  • 197
  • 27
    I had no idea this existed... it seems like it would be a major vector for security attacks. Any idea how it is secured? – rmeador Jan 08 '09 at 22:25
  • 175
    It is secured by the fact the loader will ignore LD_PRELOAD if ruid != euid -- Joshua – Joshua Jan 08 '09 at 22:30
  • 33
    @Joshua: what are ruid and euid? – heinrich5991 Nov 04 '12 at 10:27
  • 29
    @heinrich5991 Real and effective user ids: http://www.lst.de/~okir/blackhats/node23.html – gsgx Mar 02 '13 at 06:22
  • Necropost: @Joshua 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 ). – Stolas Jun 07 '13 at 13:06
  • 85
    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. – Frerich Raabe Sep 10 '13 at 11:36
  • 10
    lst.de/ link is 403 access forbidden, here is https://web.archive.org/web/20080318213813/http://www.lst.de/~okir/blackhats/node23.html – Elijah Lynn Feb 29 '16 at 12:53
  • @SathOkh: `# touch /etc/shadow` ... `touch: cannot touch '/etc/shadow': Permission denied` ... `# whoami` ... `root` ... `# ps -u -p $$ | tail -n 1 | cut -d ' ' -f 1` ... `keithb` ... – inetknght Apr 03 '17 at 17:18
  • @SathOkh lcamtuf's exploit is a joke. It pretends its *uid are zero but they are not really. – Stéphane Gourichon Mar 20 '19 at 23:45
  • Nvm, my mistake :( – SathOkh Mar 21 '19 at 09:05
  • 3
    One neat LD_PRELOAD application is [stderred](https://github.com/sickill/stderred), which causes anything written to `stderr` to be colored red in the terminal. – Roger Dahl Mar 04 '21 at 02:20
  • 1
    See also this tutorial for how to build the `*.so` shared object: https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html. – Gabriel Staples Jun 28 '21 at 22:43
67

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.

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
Joshua
  • 40,822
  • 8
  • 72
  • 132
  • 23
    "Some people use it to specify libraries in nonstandard locations"... Really? Sounds like "Some people use it wrong"! – Tom Jun 10 '11 at 07:52
  • 7
    LD_PRELOAD can by virtue of load order intercept application-specified hardcoded paths. – Joshua Jun 10 '11 at 16:05
  • 1
    Would it be a misuse to preload a different _version_ of a library - assuming they are compatible? – z0r Nov 26 '13 at 07:17
  • 2
    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. – Joshua Nov 26 '13 at 15:35
  • 1
    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. – synthesizerpatel Feb 27 '14 at 10:04
  • @z0r: It's not a misuse if you're subject to the whims of a bad system administrator and can't install things yourself. :p – synthesizerpatel Feb 27 '14 at 10:05
59

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)
    ...
Yun
  • 3,056
  • 6
  • 9
  • 28
Patric
  • 2,063
  • 17
  • 18
48

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.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Ronny Brendel
  • 4,777
  • 5
  • 35
  • 55
  • 3
    but what if the program uses `calloc`? wouldn't that mess up everything? – Janus Troelsen Sep 30 '14 at 13:13
  • 9
    @JanusTroelsen if the library you write doesn't implement a certain part, that part would be loaded from the original library. – Woodrow Barlow Oct 01 '14 at 14:42
  • @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. – sherrellbc Apr 06 '17 at 22:47
  • 3
    @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. – Joshua Jun 26 '19 at 17:36
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

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
Rajesh
  • 356
  • 1
  • 5
  • 15
8

To export mylib.so to env:

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

To disable it:

$ unset LD_PRELOAD
JulienGenoud
  • 592
  • 9
  • 21
4

Here is a detailed blog post about preloading:

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

asn
  • 798
  • 9
  • 17
  • 18
    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'.](http://stackoverflow.com/faq#deletion) 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. – Taryn Oct 06 '14 at 11:20
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.

2

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.

Yun
  • 3,056
  • 6
  • 9
  • 28