[stunnel-users] 32/64 bit interposition on Solaris

Norm Jacobs norm.jacobs at oracle.com
Fri Mar 29 22:53:45 CET 2013

I was recently working with stunnel on Solaris and ran across the 
following code in client.c:

                 putenv("LD_PRELOAD=" LIBDIR "/libstunnel.so");

This appears to have been put in place to interpose a stunnel version of 
getpeername() on the downstream application.  This works great when 
libstunnel.so has the same bittedness as the downstream application, but 
Solaris allows users to install and run both 32 and 64 bit applications 
on the same system.  If the stunnel exectuable is a 32 bit application 
and the downstream application is a 64 bit application, the runtime 
linker falls over because of the mismatch with the interposed library.  
To avoid this problem, stunnel should use LD_PRELOAD_32 and 
LD_PRELOAD_64 on Solaris.  I have put together a patch to client.c that 
sets both LD_PRELOAD_* environment variables to something that seems to 
make sense on Solaris, but have used a fairly hacky way of enabling it 
when I build.  The client.c changes that I put together are:

    # On Solaris, fix stunnel so that the linker know where both the 32 and 64 bit
    # interposer libraries are.  If you use LD_PRELOAD with the wrong bittedness
    # of interposer, the runtime linker hits a fatal error in trying to load
    # mismatched ELF objects.
    diff -r -u stunnel-4.55.orig/src/client.c stunnel-4.55/src/client.c
    --- stunnel-4.55.orig/src/client.c      2013-02-28 00:17:58.000000000 -0800
    +++ stunnel-4.55/src/client.c   2013-03-21 22:55:21.098479331 -0700
    @@ -1096,9 +1096,14 @@
                  /* just don't set these variables if getnameinfo() fails */
                  putenv(str_printf("REMOTE_HOST=%s", host));
                  if(c->opt->option.transparent_src) {
    -                putenv("LD_PRELOAD=" LIBDIR "/libstunnel.so");
    -                /* for Tru64 _RLD_LIST is used instead */
    +#ifdef MACH64
    +                putenv("LD_PRELOAD_32=" LIBDIR "/libstunnel.so");
    +                putenv("LD_PRELOAD_64=" LIBDIR "/" MACH64 "/libstunnel.so");
    +#elif __osf /* for Tru64 _RLD_LIST is used instead */
                      putenv("_RLD_LIST=" LIBDIR "/libstunnel.so:DEFAULT");
    +                putenv("LD_PRELOAD=" LIBDIR "/libstunnel.so");

This adds more appropriate environment variables into the calling 
environment on Solaris.  It still needs some work to integrate better 
with the build.  Anyway, I thought that I would raise the issue and at 
least offer a direction to work from.  I am happy to work with someone 
on a better resolution to this.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.stunnel.org/pipermail/stunnel-users/attachments/20130329/cd3adcf5/attachment.html>

More information about the stunnel-users mailing list