Hi Ralf,

On Fri, 2009-06-12 at 21:57 +0200, Michael Haubenwallner wrote:

> > > > Hmm.  This does open a small security issue, no?
> > 
> > That's precisely the reason we haven't gone this way
> > before.
> 
> Asking HP people (or more carefully reading the manpage) does help: The
> linker does have the "+cdp" flag, which allows for changing the linktime
> path of a library into something different being stored as fallback path
> into the binary. It does even work on hpux10.20 (ld B.10.37 here)
> although not mentioned in its manpage.

Here's a patch that uses the +cdp linker flag to close the security
issue with the fallback path encoded into the SOM binaries, by adding
another libtool property 'fix_hardcoded_libdir_flag_spec', only used for
hppa-hpux (32bit). It is configure-checked if compiler/linker do support
this flag.

This allows for hardcode_action=immediate and fast_install=yes, required
for DESTDIR support.

tests/deplibs-ident.at has to filter this flag, as it would lead to
false positives.

The same 12 tests as before are turned from SKIP/XFAIL to PASS on all
the setups as before, with one exception: It is collect2 of gcc-3.0.1 on
hppa-hpux10 here, which erroneously interprets -Wl,+cdp and fails to
find libraries. So no tests do change their result in this setup.

Thank you!

/haubi/
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 6f44d35..f7d098d 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -3801,6 +3801,8 @@ func_mode_link ()
     lib_search_path=`pwd`
     inst_prefix_dir=
     new_inherited_linker_flags=
+    fix_hardcoded_libdir_flag=
+    fix_hardcoded_libdir_flag_ld=
 
     avoid_version=no
     dlfiles=
@@ -5436,6 +5438,15 @@ func_mode_link ()
 	      elif test "$hardcode_shlibpath_var" = no; then
 		add_shlibpath="$dir"
 		add="-l$name"
+	      elif test -n "$fix_hardcoded_libdir_flag_spec"; then
+		add_dir="-L${absdir}"
+		add="-l$name"
+		if test "${linkmode}" = prog && test "X${absdir}" != "X${libdir}"; then
+		  linkdir=$absdir
+		  eval "fix_hardcoded_libdir_flag=\"\${fix_hardcoded_libdir_flag} ${fix_hardcoded_libdir_flag_spec}\""
+		  # fix_hardcoded_libdir_flag_ld not needed, programs are linked with $CC
+		  $lt_unset linkdir
+		fi
 	      else
 		lib_linked=no
 	      fi
@@ -5503,6 +5514,15 @@ func_mode_link ()
 	    elif test "$hardcode_minus_L" = yes; then
 	      add_dir="-L$libdir"
 	      add="-l$name"
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" &&
+		 test -n "${fix_hardcoded_libdir_flag_spec}"; then
+		linkdir="$inst_prefix_dir$libdir"
+		add_dir="-L$linkdir"
+		eval "fix_hardcoded_libdir_flag=\"\${fix_hardcoded_libdir_flag} ${fix_hardcoded_libdir_flag_spec}\""
+		eval "fix_hardcoded_libdir_flag_ld=\"\${fix_hardcoded_libdir_flag_ld} ${fix_hardcoded_libdir_flag_spec_ld}\""
+		$lt_unset linkdir
+	      fi
 	    elif test "$hardcode_shlibpath_var" = yes; then
 	      case :$finalize_shlibpath: in
 	      *":$libdir:"*) ;;
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index 5f24fab..9907f66 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -1905,6 +1905,7 @@ if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
      ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test -z "$_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)" &&
      test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
     # Linking always hardcodes the temporary library directory.
     _LT_TAGVAR(hardcode_action, $1)=relink
@@ -4175,6 +4176,8 @@ m4_if([$1], [CXX], [
   _LT_TAGVAR(hardcode_libdir_separator, $1)=
   _LT_TAGVAR(hardcode_minus_L, $1)=no
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+  _LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
   _LT_TAGVAR(inherit_rpath, $1)=no
   _LT_TAGVAR(link_all_deplibs, $1)=unknown
   _LT_TAGVAR(module_cmds, $1)=
@@ -4758,13 +4761,12 @@ _LT_EOF
 
     hpux10*)
       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
       fi
       if test "$with_gnu_ld" = no; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-	_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir $fix_hardcoded_libdir_flag'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
@@ -4772,6 +4774,22 @@ _LT_EOF
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+	# gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+	# HP-cc ignores -Wl,+cdp, and we test the linker for +cdp support.
+	AC_CACHE_CHECK([if +cdp linker flag works],
+	  [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)],
+	  [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no
+	  save_LDFLAGS=$LDFLAGS
+	  LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+	  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	    [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=yes],
+	    [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no])
+	  LDFLAGS="$save_LDFLAGS"
+	])
+	if test "$_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)" = yes; then
+	  _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+	  _LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)='+cdp ${linkdir}/${dlname}:${libdir}/${dlname}'
+	fi
       fi
       ;;
 
@@ -4785,7 +4803,7 @@ _LT_EOF
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
 	  ;;
 	esac
       else
@@ -4802,14 +4820,14 @@ _LT_EOF
 	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
 	  _LT_LINKER_OPTION([if $CC understands -b],
 	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
-	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
-	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
-	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'])
 	  ;;
 	esac
       fi
       if test "$with_gnu_ld" = no; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir $fix_hardcoded_libdir_flag'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	case $host_cpu in
@@ -4825,6 +4843,22 @@ _LT_EOF
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
 	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+	  # HP-cc ignores -Wl,+cdp, and we test the linker for +cdp support.
+	  AC_CACHE_CHECK([if +cdp linker flag works],
+	    [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)],
+	    [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no
+	    save_LDFLAGS=$LDFLAGS
+	    LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+	    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	      [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=yes],
+	      [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no])
+	    LDFLAGS="$save_LDFLAGS"
+	  ])
+	  if test "$_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)" = yes; then
+	    _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+	    _LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)='+cdp ${linkdir}/${dlname}:${libdir}/${dlname}'
+	  fi
 	  ;;
 	esac
       fi
@@ -5214,6 +5248,10 @@ _LT_TAGDECL([], [hardcode_automatic], [0],
     [Set to "yes" if building a shared library automatically hardcodes DIR
     into the library and all subsequent libraries and executables linked
     against it])
+_LT_TAGDECL([], [fix_hardcoded_libdir_flag_spec], [1],
+    [Flag to modify a path being hardcoded into the resulting binary])
+_LT_TAGDECL([], [fix_hardcoded_libdir_flag_spec_ld], [1],
+    [If ld is used when linking, flag to modify a path being hardcoded into the resulting binary])
 _LT_TAGDECL([], [inherit_rpath], [0],
     [Set to yes if linker adds runtime paths of dependent libraries
     to runtime path list])
@@ -5355,6 +5393,8 @@ _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
 _LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(inherit_rpath, $1)=no
 _LT_TAGVAR(module_cmds, $1)=
 _LT_TAGVAR(module_expsym_cmds, $1)=
@@ -5729,7 +5769,7 @@ if test "$_lt_caught_CXX_error" != yes; then
 
       hpux10*|hpux11*)
         if test $with_gnu_ld = no; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir $fix_hardcoded_libdir_flag'
 	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
           case $host_cpu in
@@ -5751,6 +5791,21 @@ if test "$_lt_caught_CXX_error" != yes; then
             _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
 					         # but as the default
 					         # location of the library.
+	    # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+	    # HP-aCC ignores -Wl,+cdp, and we test the linker for +cdp support.
+	    AC_CACHE_CHECK([if +cdp linker flag works],
+	      [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)],
+	      [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no
+	      save_LDFLAGS=$LDFLAGS
+	      LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+	      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+		[_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=yes],
+		[_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no])
+	      LDFLAGS="$save_LDFLAGS"
+	    ])
+	    if test "$_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)" = yes; then
+	      _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+	    fi
             ;;
         esac
 
@@ -5768,7 +5823,7 @@ if test "$_lt_caught_CXX_error" != yes; then
 	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $fix_hardcoded_libdir_flag'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -5792,7 +5847,7 @@ if test "$_lt_caught_CXX_error" != yes; then
 	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $fix_hardcoded_libdir_flag'
 	            ;;
 	        esac
 	      fi
@@ -6589,6 +6644,8 @@ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(inherit_rpath, $1)=no
 _LT_TAGVAR(module_cmds, $1)=
 _LT_TAGVAR(module_expsym_cmds, $1)=
@@ -6719,6 +6776,8 @@ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(inherit_rpath, $1)=no
 _LT_TAGVAR(module_cmds, $1)=
 _LT_TAGVAR(module_expsym_cmds, $1)=
diff --git a/tests/deplibs-ident.at b/tests/deplibs-ident.at
index 5758311..64d4d0b 100644
--- a/tests/deplibs-ident.at
+++ b/tests/deplibs-ident.at
@@ -65,8 +65,17 @@ int main() { return a1() + a2() + a3() + c(); }
   AT_CHECK([$CC $CFLAGS -c b.c],[0],[ignore],[ignore])
   AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o b$EXEEXT b.$OBJEXT ../liba1.la ../liba2.la ../liba3.la ../../c/libcee.la -rpath /nowhere],
 	   [0],[stdout],[ignore])
-  AT_CHECK([$EGREP 'cee.*cee' stdout], 1, [ignore], [ignore])
+  : ${SED="sed"}
+  eval `$LIBTOOL --config | $EGREP '^fix_hardcoded_libdir_flag_spec=' | $SED -e 's/\\+/\\\\+/g'`
+  readstdout="cat stdout"
+  if test -n "${fix_hardcoded_libdir_flag_spec}"; then
+    linkdir='[[^ ]]*'
+    libdir='[[^ ]]*'
+    dlname='[[^ ]]*'
+    eval "readstdout=\"\${SED} -e 's#${fix_hardcoded_libdir_flag_spec}##g' stdout\""
+  fi
+  AT_CHECK([eval $readstdout | $EGREP 'cee.*cee'], 1, [ignore], [ignore])
   AT_XFAIL_IF([case $host in
                  *-*-aix*|hppa*-*-hpux*|*-*-interix*|*-*-openbsd*) false;;
                  *):;;
                esac])

Reply via email to