This is the mail archive of the libc-alpha@sources.redhat.com 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]

LD_PRELOAD and dlopen


I am writing an LD_PRELOAD library that needs to intercept the dlopen()
call. I must make the library compile under both Linux and Solaris. Solaris
works fine, but I am having some trouble with Linux.

I need to wrap the dlopen() call for various reasons.

I have listed some simple code below to highlight the problem...

Here is my test binary. It simply executes a couple of system calls - dlopen
and close. Close is just a simple call to use as a control case.

include <stdio.h>
include <dlfcn.h>

int main()
{
    void* handle;

    printf("calling close...\n");
    close( 12345 );
    printf("close called.\n");

    printf("calling dlopen...\n");
    handle = dlopen( "somefile", 0 );
    printf("dlopen called.\n");
}

In all cases this is compiled with...

# gcc -ldl test.c

Here is my preload library. It wraps the close and dlopen calls.

#include <dlfcn.h>
#include <stdio.h>

#if defined(RTLD_NEXT)
#define REAL_LIBC RTLD_NEXT
#else
#define REAL_LIBC ((void *) -1L)
#endif

void* dlopen(const char *file, int mode)
{
    static void* (*o_dlopen) ( const char *file, int mode )=0;
    printf( "dlopen was called\n" );
    o_dlopen = (void*(*)(const char *file, int mode)) dlsym(REAL_LIBC,
"dlopen");
    return (*o_dlopen)( file, mode );
}

int close( int fd )
{
    static int (*o_close) ( int fd )=0;
    printf( "close was called\n" );
    o_close = (int(*)( int fd )) dlsym(REAL_LIBC, "close");
    return (*o_close)( fd );
}

Here are my attempts at getting it working:

SUCCESS - Solaris with -ldl
===========================
# make
gcc -Wall -ldl -fPIC -shared -o preload.so preload.c
ls -al *.so
-rwxr-xr-x   1 root     other       6536 May 29 18:05 preload.so
# export
LD_PRELOAD=/configroot/devteam-only/cgi/LD_PRELOAD/dlopentest/preload.so
# ./a.out
calling close...
close was called
close called.
calling dlopen...
dlopen was called
dlopen called.
#
# cp Makefile Makefile2
close was called
close was called
#

SUCCESS - Solaris without -ldl
==============================
# make
gcc -Wall -fPIC -shared -o preload.so preload.c
ls -al *.so
-rwxr-xr-x   1 root     other       6360 May 29 18:08 preload.so
bash-2.02# export
LD_PRELOAD=/configroot/devteam-only/cgi/LD_PRELOAD/dlopentest/preload.so
bash-2.02# ./a.out
calling close...
close was called
close called.
calling dlopen...
dlopen was called
dlopen called.
#
# cp Makefile Makefile2
close was called
close was called
#

FAILED - Linux with -ldl
========================
# make
gcc -Wall -ldl -fPIC -shared -o preload.so preload.c
/usr/bin/ld: preload.so: undefined versioned symbol name dlopen@@GLIBC_2.1
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
make: *** [preload.so] Error 1
#

FAILED - Linux without -ldl
===========================
# make
gcc -Wall -fPIC -shared -o preload.so preload.c
ls -al *.so
-rwxr-xr-x    1 root     root         6166 May 29 19:12 preload.so
# gcc -ldl binlin.c
# export
LD_PRELOAD=/configroot/devteam-only/cgi/LD_PRELOAD/dlopentest/preload.so
# ./a.out
calling close...
close was called
close called.
calling dlopen...
dlopen was called
dlopen called.
#
# cp Makefile Makefile2
cp: overwrite `Makefile2'? y
close was called
cp: error in loading shared libraries:
/configroot/devteam-only/cgi/LD_PRELOAD/dlopentest/preload.so: undefined
symbol: dlsym

My diagnosis of this is that the Linux cp command is failing because it is
statically linked. Because of this, the symbol dlopen cannot be found and
the process bombs. I need to link in the 'dl' library by using '-ldl' during
compilation, but this gives the errors above.

Does anyone have any ideas on how to fix this ?

libc version on linux is 2.1.3.
Linux kernel is 2.2.19.

Thanks in advance

Steve

----
Stephen Done           steve@ukmail.org / stephen.done@cw.com
Cable & Wireless Global


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