Quiz Entry - updated: 2026.07.10
How does LD_PRELOAD work with the dynamic linker?
LD_PRELOAD libraries are searched first, so their symbols win the resolution; the wrapper then reaches the real function with dlsym(RTLD_NEXT, ...).
* The preloaded library jumps to the front of the search, so its malloc wins; dlsym(RTLD_NEXT, ...) then reaches past it to the real one in libc. *
Normal symbol resolution order:
- Main executable
- Libraries in link order
- libc
With LD_PRELOAD=./mymalloc.so:
- mymalloc.so ← searched first!
- Main executable
- Libraries in link order
- libc
How the wrapper calls the real function:
// In mymalloc.so
void *malloc(size_t size) {
// RTLD_NEXT: skip mymalloc.so, search remaining libraries
void *(*real_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc");
// Now real_malloc points to libc's malloc
void *ptr = real_malloc(size);
// ... do something with ptr ...
return ptr;
}
Environment variables:
LD_PRELOAD- libraries to load before all othersLD_LIBRARY_PATH- directories to search for libraries
Security note: LD_PRELOAD is ignored for setuid/setgid binaries to prevent privilege escalation.
Go deeper:
ld.so(8) — LD_PRELOAD and the search order — the authoritative rules, including why it's dropped for setuid binaries.