This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Possible bug with dlsym and LD_PRELOAD


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]