Possible bug with dlsym and LD_PRELOAD
Paul Pluzhnikov
ppluzhnikov@google.com
Tue Aug 21 14:17:00 GMT 2012
On Tue, Aug 21, 2012 at 12:14 AM, Paul Millar <paul.millar@desy.de> wrote:
> 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.
The bug appears to be in your program. From "man dlsym":
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT.
The former will find the first occurrence of the desired symbol using
the default library search order. The latter will find the next
occurrence of a function in the search order after the current
library. This allows one to provide a wrapper around a function in
another shared library.
You want RTLD_NEXT in wrapper.c, but not in hello.c. Changing hello.c
to use RTLD_DEFAULT produces:
LD_PRELOAD=./libwrapper.so ./test-dynamic
=== WRAPPED: begin ===
Hello, world (direct)
=== WRAPPED: end ===
=== WRAPPED: begin ===
Hello, world (via dlsym)
=== WRAPPED: end ===
> 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
There is also a bug in your sources: wrapper.c is missing <stdlib.h>,
which makes it fail to build like so:
cc -Wall -c wrapper.c -o wrapper.lo -fPIC
wrapper.c:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘write’
make: *** [wrapper.lo] Error 1
>
> 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:
Not that it matters, but saying "on my machine" gives us no
information about it. What version of glibc is installed on your
machine?
>
> ---
> --- 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.
HTH,
--
Paul Pluzhnikov
More information about the Libc-help
mailing list