Allow asan, msan and ubsan to be configured with shared libraries
authorRichard Levitte <levitte@openssl.org>
Wed, 7 Sep 2016 18:56:20 +0000 (20:56 +0200)
committerRichard Levitte <richard@levitte.org>
Wed, 7 Sep 2016 19:54:08 +0000 (21:54 +0200)
The background story is that util/shlib_wrap.sh was setting LD_PRELOAD
or similar platform dependent variables, just in case the shared
libraries were built with -rpath.  Unfortunately, this doesn't work
too well with asan, msan or ubsan.

So, the solution is to forbid the combination of shared libraries,
-rpath and any of the sanity analyzers we can configure.

This changes util/shlib_wrap.sh so it only contains the code that sets
LD_PRELOAD when -rpath has been used when configuring.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(cherry picked from commit 342a1a23793cb99921abeabe882adf8652ba715d)

Configurations/unix-Makefile.tmpl
Configure
util/build.info [new file with mode: 0644]
util/shlib_wrap.sh [deleted file]
util/shlib_wrap.sh.in [new file with mode: 0755]

index 1392295607aa04985c6f3a63fb7e4df57f1be46e..d486d9e2aba5597f583df740562add9f732d845b 100644 (file)
@@ -775,18 +775,14 @@ dist:
 
 # Helper targets #####################################################
 
-link-utils: $(BLDDIR)/util/opensslwrap.sh $(BLDDIR)/util/shlib_wrap.sh
+link-utils: $(BLDDIR)/util/opensslwrap.sh
 
 $(BLDDIR)/util/opensslwrap.sh: configdata.pm
        @if [ "$(SRCDIR)" != "$(BLDDIR)" ]; then \
            mkdir -p "$(BLDDIR)/util"; \
            ln -sf "../$(SRCDIR)/util/opensslwrap.sh" "$(BLDDIR)/util"; \
        fi
-$(BLDDIR)/util/shlib_wrap.sh: configdata.pm
-       @if [ "$(SRCDIR)" != "$(BLDDIR)" ]; then \
-           mkdir -p "$(BLDDIR)/util"; \
-           ln -sf "../$(SRCDIR)/util/shlib_wrap.sh" "$(BLDDIR)/util"; \
-       fi
+
 FORCE:
 
 # Building targets ###################################################
index f77177f25c4173f83b8741c369351b025bfff650..4be1f33e534c29353d142f8e414d8aa7913802d2 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -284,7 +284,7 @@ my $default_ranlib;
 $config{fips}=0;
 
 # Top level directories to build
-$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools", "fuzz" ];
+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
 # crypto/ subdirectories to build
 $config{sdirs} = [
     "objects",
@@ -763,6 +763,13 @@ foreach (@argvcopy)
                }
        }
 
+if ($libs =~ /(^|\s)-Wl,-rpath,/
+    && !$disabled{shared}
+    && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
+    die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
+       "***** any of asan, msan or ubsan\n";
+}
+
 if ($config{fips})
        {
        delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
diff --git a/util/build.info b/util/build.info
new file mode 100644 (file)
index 0000000..616fbd7
--- /dev/null
@@ -0,0 +1,2 @@
+SCRIPTS_NO_INST=shlib_wrap.sh
+SOURCE[shlib_wrap.sh]=shlib_wrap.sh.in
diff --git a/util/shlib_wrap.sh b/util/shlib_wrap.sh
deleted file mode 100755 (executable)
index ce463f1..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/sh
-
-[ $# -ne 0 ] || set -x         # debug mode without arguments:-)
-
-THERE="`echo $0 | sed -e 's|[^/]*$||' 2>/dev/null`.."
-[ -d "${THERE}" ] || exec "$@" # should never happen...
-
-# Alternative to this is to parse ${THERE}/Makefile...
-LIBCRYPTOSO="${THERE}/libcrypto.so"
-if [ -f "$LIBCRYPTOSO" ]; then
-    while [ -h "$LIBCRYPTOSO" ]; do
-       LIBCRYPTOSO="${THERE}/`ls -l "$LIBCRYPTOSO" | sed -e 's|.*\-> ||'`"
-    done
-    SOSUFFIX=`echo ${LIBCRYPTOSO} | sed -e 's|.*\.so||' 2>/dev/null`
-    LIBSSLSO="${THERE}/libssl.so${SOSUFFIX}"
-fi
-
-SYSNAME=`(uname -s) 2>/dev/null`;
-case "$SYSNAME" in
-SunOS|IRIX*)
-       # SunOS and IRIX run-time linkers evaluate alternative
-       # variables depending on target ABI...
-       rld_var=LD_LIBRARY_PATH
-       case "`(/usr/bin/file "$LIBCRYPTOSO") 2>/dev/null`" in
-       *ELF\ 64*SPARC*|*ELF\ 64*AMD64*)
-               [ -n "$LD_LIBRARY_PATH_64" ] && rld_var=LD_LIBRARY_PATH_64
-               LD_PRELOAD_64="$LIBCRYPTOSO $LIBSSLSO"; export LD_PRELOAD_64
-               preload_var=LD_PRELOAD_64
-               ;;
-       *ELF\ 32*SPARC*|*ELF\ 32*80386*)
-               # We only need to change LD_PRELOAD_32 and LD_LIBRARY_PATH_32
-               # on a multi-arch system.  Otherwise, trust the fallbacks.
-               if [ -f /lib/64/ld.so.1 ]; then
-                   [ -n "$LD_LIBRARY_PATH_32" ] && rld_var=LD_LIBRARY_PATH_32
-                   LD_PRELOAD_32="$LIBCRYPTOSO $LIBSSLSO"; export LD_PRELOAD_32
-                   preload_var=LD_PRELOAD_32
-               fi
-               ;;
-       # Why are newly built .so's preloaded anyway? Because run-time
-       # .so lookup path embedded into application takes precedence
-       # over LD_LIBRARY_PATH and as result application ends up linking
-       # to previously installed .so's. On IRIX instead of preloading
-       # newly built .so's we trick run-time linker to fail to find
-       # the installed .so by setting _RLD_ROOT variable.
-       *ELF\ 32*MIPS*)
-               #_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD_LIST
-               _RLD_ROOT=/no/such/dir; export _RLD_ROOT
-               eval $rld_var=\"/usr/lib'${'$rld_var':+:$'$rld_var'}'\"
-               preload_var=_RLD_LIST
-               ;;
-       *ELF\ N32*MIPS*)
-               [ -n "$LD_LIBRARYN32_PATH" ] && rld_var=LD_LIBRARYN32_PATH
-               #_RLDN32_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLDN32_LIST
-               _RLDN32_ROOT=/no/such/dir; export _RLDN32_ROOT
-               eval $rld_var=\"/usr/lib32'${'$rld_var':+:$'$rld_var'}'\"
-               preload_var=_RLDN32_LIST
-               ;;
-       *ELF\ 64*MIPS*)
-               [ -n "$LD_LIBRARY64_PATH"  ] && rld_var=LD_LIBRARY64_PATH
-               #_RLD64_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD64_LIST
-               _RLD64_ROOT=/no/such/dir; export _RLD64_ROOT
-               eval $rld_var=\"/usr/lib64'${'$rld_var':+:$'$rld_var'}'\"
-               preload_var=_RLD64_LIST
-               ;;
-       esac
-       eval $rld_var=\"${THERE}'${'$rld_var':+:$'$rld_var'}'\"; export $rld_var
-       unset rld_var
-       ;;
-*)     LD_LIBRARY_PATH="${THERE}:$LD_LIBRARY_PATH"     # Linux, ELF HP-UX
-       DYLD_LIBRARY_PATH="${THERE}:$DYLD_LIBRARY_PATH" # MacOS X
-       SHLIB_PATH="${THERE}:$SHLIB_PATH"               # legacy HP-UX
-       LIBPATH="${THERE}:$LIBPATH"                     # AIX, OS/2
-       export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH
-       # Even though $PATH is adjusted [for Windows sake], it doesn't
-       # necessarily does the trick. Trouble is that with introduction
-       # of SafeDllSearchMode in XP/2003 it's more appropriate to copy
-       # .DLLs in vicinity of executable, which is done elsewhere...
-       if [ "$OSTYPE" != msdosdjgpp ]; then
-               PATH="${THERE}:$PATH"; export PATH
-       fi
-       ;;
-esac
-
-if [ -f "$LIBCRYPTOSO" -a -z "$preload_var" ]; then
-       # Following three lines are major excuse for isolating them into
-       # this wrapper script. Original reason for setting LD_PRELOAD
-       # was to make it possible to pass 'make test' when user linked
-       # with -rpath pointing to previous version installation. Wrapping
-       # it into a script makes it possible to do so on multi-ABI
-       # platforms.
-       case "$SYSNAME" in
-       *BSD|QNX)       LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;;  # *BSD, QNX
-       *)      LD_PRELOAD="$LIBCRYPTOSO $LIBSSLSO" ;;  # SunOS, Linux, ELF HP-UX
-       esac
-       _RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"      # Tru64, o32 IRIX
-       DYLD_INSERT_LIBRARIES="$LIBCRYPTOSO:$LIBSSLSO"  # MacOS X
-       export LD_PRELOAD _RLD_LIST DYLD_INSERT_LIBRARIES
-fi
-
-cmd="$1"; [ -x "$cmd" ] || cmd="$cmd${EXE_EXT}"
-shift
-if [ $# -eq 0 ]; then
-       exec "$cmd"     # old sh, such as Tru64 4.x, fails to expand empty "$@"
-else
-       exec "$cmd" "$@"
-fi
diff --git a/util/shlib_wrap.sh.in b/util/shlib_wrap.sh.in
new file mode 100755 (executable)
index 0000000..eff1141
--- /dev/null
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+[ $# -ne 0 ] || set -x         # debug mode without arguments:-)
+
+THERE="`echo $0 | sed -e 's|[^/]*$||' 2>/dev/null`.."
+[ -d "${THERE}" ] || exec "$@" # should never happen...
+
+# Alternative to this is to parse ${THERE}/Makefile...
+LIBCRYPTOSO="${THERE}/libcrypto.so"
+if [ -f "$LIBCRYPTOSO" ]; then
+    while [ -h "$LIBCRYPTOSO" ]; do
+       LIBCRYPTOSO="${THERE}/`ls -l "$LIBCRYPTOSO" | sed -e 's|.*\-> ||'`"
+    done
+    SOSUFFIX=`echo ${LIBCRYPTOSO} | sed -e 's|.*\.so||' 2>/dev/null`
+    LIBSSLSO="${THERE}/libssl.so${SOSUFFIX}"
+fi
+
+SYSNAME=`(uname -s) 2>/dev/null`;
+case "$SYSNAME" in
+SunOS|IRIX*)
+       # SunOS and IRIX run-time linkers evaluate alternative
+       # variables depending on target ABI...
+       rld_var=LD_LIBRARY_PATH
+       case "`(/usr/bin/file "$LIBCRYPTOSO") 2>/dev/null`" in
+       *ELF\ 64*SPARC*|*ELF\ 64*AMD64*)
+               [ -n "$LD_LIBRARY_PATH_64" ] && rld_var=LD_LIBRARY_PATH_64
+               LD_PRELOAD_64="$LIBCRYPTOSO $LIBSSLSO"; export LD_PRELOAD_64
+               preload_var=LD_PRELOAD_64
+               ;;
+       *ELF\ 32*SPARC*|*ELF\ 32*80386*)
+               # We only need to change LD_PRELOAD_32 and LD_LIBRARY_PATH_32
+               # on a multi-arch system.  Otherwise, trust the fallbacks.
+               if [ -f /lib/64/ld.so.1 ]; then
+                   [ -n "$LD_LIBRARY_PATH_32" ] && rld_var=LD_LIBRARY_PATH_32
+                   LD_PRELOAD_32="$LIBCRYPTOSO $LIBSSLSO"; export LD_PRELOAD_32
+                   preload_var=LD_PRELOAD_32
+               fi
+               ;;
+       # Why are newly built .so's preloaded anyway? Because run-time
+       # .so lookup path embedded into application takes precedence
+       # over LD_LIBRARY_PATH and as result application ends up linking
+       # to previously installed .so's. On IRIX instead of preloading
+       # newly built .so's we trick run-time linker to fail to find
+       # the installed .so by setting _RLD_ROOT variable.
+       *ELF\ 32*MIPS*)
+               #_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD_LIST
+               _RLD_ROOT=/no/such/dir; export _RLD_ROOT
+               eval $rld_var=\"/usr/lib'${'$rld_var':+:$'$rld_var'}'\"
+               preload_var=_RLD_LIST
+               ;;
+       *ELF\ N32*MIPS*)
+               [ -n "$LD_LIBRARYN32_PATH" ] && rld_var=LD_LIBRARYN32_PATH
+               #_RLDN32_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLDN32_LIST
+               _RLDN32_ROOT=/no/such/dir; export _RLDN32_ROOT
+               eval $rld_var=\"/usr/lib32'${'$rld_var':+:$'$rld_var'}'\"
+               preload_var=_RLDN32_LIST
+               ;;
+       *ELF\ 64*MIPS*)
+               [ -n "$LD_LIBRARY64_PATH"  ] && rld_var=LD_LIBRARY64_PATH
+               #_RLD64_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD64_LIST
+               _RLD64_ROOT=/no/such/dir; export _RLD64_ROOT
+               eval $rld_var=\"/usr/lib64'${'$rld_var':+:$'$rld_var'}'\"
+               preload_var=_RLD64_LIST
+               ;;
+       esac
+       eval $rld_var=\"${THERE}'${'$rld_var':+:$'$rld_var'}'\"; export $rld_var
+       unset rld_var
+       ;;
+*)     LD_LIBRARY_PATH="${THERE}:$LD_LIBRARY_PATH"     # Linux, ELF HP-UX
+       DYLD_LIBRARY_PATH="${THERE}:$DYLD_LIBRARY_PATH" # MacOS X
+       SHLIB_PATH="${THERE}:$SHLIB_PATH"               # legacy HP-UX
+       LIBPATH="${THERE}:$LIBPATH"                     # AIX, OS/2
+       export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH
+       # Even though $PATH is adjusted [for Windows sake], it doesn't
+       # necessarily does the trick. Trouble is that with introduction
+       # of SafeDllSearchMode in XP/2003 it's more appropriate to copy
+       # .DLLs in vicinity of executable, which is done elsewhere...
+       if [ "$OSTYPE" != msdosdjgpp ]; then
+               PATH="${THERE}:$PATH"; export PATH
+       fi
+       ;;
+esac
+
+{- output_off() if $config{ex_libs} !~ /(^|\s)-Wl,-rpath,/; ""; -}
+if [ -f "$LIBCRYPTOSO" -a -z "$preload_var" ]; then
+       # Following three lines are major excuse for isolating them into
+       # this wrapper script. Original reason for setting LD_PRELOAD
+       # was to make it possible to pass 'make test' when user linked
+       # with -rpath pointing to previous version installation. Wrapping
+       # it into a script makes it possible to do so on multi-ABI
+       # platforms.
+       case "$SYSNAME" in
+       *BSD|QNX)       LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;;  # *BSD, QNX
+       *)      LD_PRELOAD="$LIBCRYPTOSO $LIBSSLSO" ;;  # SunOS, Linux, ELF HP-UX
+       esac
+       _RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"      # Tru64, o32 IRIX
+       DYLD_INSERT_LIBRARIES="$LIBCRYPTOSO:$LIBSSLSO"  # MacOS X
+       export LD_PRELOAD _RLD_LIST DYLD_INSERT_LIBRARIES
+fi
+{- output_on() if $config{ex_libs} !~ /(^|\s)-Wl,-rpath,/; ""; -}
+
+cmd="$1"; [ -x "$cmd" ] || cmd="$cmd${EXE_EXT}"
+shift
+if [ $# -eq 0 ]; then
+       exec "$cmd"     # old sh, such as Tru64 4.x, fails to expand empty "$@"
+else
+       exec "$cmd" "$@"
+fi