Possible bug with dlsym and LD_PRELOAD
Paul Millar
paul.millar@desy.de
Tue Aug 21 07:15:00 GMT 2012
Hi,
I'm trying to use the LD_PRELOAD to override symbol bindings, to allow
alternative behaviour. While doing this, I've found something that
could be a bug and wanted to ask people's opinion before submitting a
bug-report.
I'm having difficulty with a program that calls a library where it's
this library makes the calls I wish to override. The complication comes
that this library doesn't have concrete references to these symbols, so
the compiled SO doesn't mention them. Instead, it uses dlsym(RTLD_NEXT,
...) to discover them "dynamically" at runtime. I've found that
LD_PRELOAD is ineffective under these circumstances.
I've written a simple test-case that demonstrates the problem:
http://www.desy.de/~paul/libc/test-dlsym-1.0.tar.gz
In this example, there are four ways of calling write(2) : in the main
code (both directly and with dlsym) and in a small library (again both
directly and with dlsym). There's also a small wrapper library that,
when loaded with LD_PRELOAD, intercepts calls to write and adds a
single-line header and footer to each call.
Running make will build the code and demonstration the problem. The
Makefile will build two binaries and two libraries:
test-static (program that uses write, directly and with dlsym, to
print two lines),
test-dynamic (program that makes a single call to libhello.so),
libhello.so (library that using write, directly and with dlsym, to
print two lines), and
libwrapper.so (library that intercepts calls to write and adds a
header and footer).
On my machine, I see the following output:
---
--- First, we run the code without any LD_PRELOAD, demonstrating correct
behaviour.
--- with an executable calling 'write' directly and via dlsym:
---
./test-static
Hello, world (direct)
Hello, world (via dlsym)
---
--- and with an executable calling a library that makes these calls:
---
./test-dynamic
Hello, world (direct)
Hello, world (via dlsym)
---
--- Run static code, but with libwrapper.so preloaded
---
LD_PRELOAD=./libwrapper.so ./test-static
=== WRAPPED: begin ===
Hello, world (direct)
=== WRAPPED: end ===
=== WRAPPED: begin ===
Hello, world (via dlsym)
=== WRAPPED: end ===
---
--- Run dynamic code, but with libwrapper.so preloaded
---
LD_PRELOAD=./libwrapper.so ./test-dynamic
=== WRAPPED: begin ===
Hello, world (direct)
=== WRAPPED: end ===
Hello, world (via dlsym)
Note that, when test-dynamic is called with libwrapper.so preloaded, the
dynamic linker resolves using LD_PRELOAD for the symbols declared in the
SO ELF structure, but later (with dlsym) the linker seems to ignore
LD_PRELOAD.
The ld.so man page is a little vague about what should happen here, but
it looks to me like a bug.
Cheers,
Paul.
More information about the Libc-help
mailing list