1/29/08   Drop-in Thread-safe Replacement for gethostbyname

Recently I’ve had the pleasure to be working with a closed source product (a big BPM vendor’s workflow engine) on Linux. Not the latest version, but fairly recent. We used to run it on Solaris but have now moved to Linux, and have been bitten by the change in thread-safety of gethostbyname.

gethostbyname allocates its own buffer for the returned structure, and in the case of Linux this buffer is the same every time you call it. If you’re writing a multi-threaded program with pthreads, this is not good. Of course, there is a re-entrant version (gethostbyname_r) but the application doesn’t use it.

The Solution

Well, thank goodness we’re on Linux with glibc, so at least the C library is open source and can be changed. The solution springing immediately to mind was to rewrite the function and recompile the library, but then I wondered if something clever could be done with the linker. And guess what? It can.

The environment variable LD_PRELOAD allows you to specify a dynamic library which is loaded in before any of the other dependencies of the executable. This means you can create a library with a thread-safe gethostbyname in it, and pre-load it before glibc in order to override the function. For security reasons, you can’t do this on executables which are setuid or setgid anything other than your current user and group (or you’re root).

$ LD_PRELOAD=libthreadsafe.so LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH stupidprogram

All that’s left is to write the replacement function. This is fairly trivial using pthreads—just use pthread_getspecific and pthread_setspecific to maintain a thread-local buffer for each thread, call gethostbyname_r with that buffer, and then return it. The client code gets the same buffer for each thread every time, rather than the same buffer for each process.

The source code can be found at http://homepage.mac.com/tapinacom/code/threadsafelib.c. Compile it with:

$ gcc -shared -Wl,-soname,libthreadsafe.so.1 -o libthreadsafe.so.1.0 threadsafelib.c -lpthread

Footnote

Incidentally, I never realised pthreads was so easy to develop in. I always assumed threading in C would be something of a black art, but it’s just as easy as it is in Java. Coding in nano was no substitute for IntelliJ, though!