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");
+#else
+ putenv("LD_PRELOAD=" LIBDIR "/libstunnel.so");
+#endif
}
}
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.
-Norm