Merge pull request #107596 from Mic92/fix-static-pie-take2

bintools-wrapper: skip dynamic linker for static binaries
This commit is contained in:
Jörg Thalheim 2020-12-30 06:23:09 +00:00 committed by GitHub
commit c417247cf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 19 deletions

View File

@ -3,6 +3,7 @@ var_templates_list=(
NIX_IGNORE_LD_THROUGH_GCC NIX_IGNORE_LD_THROUGH_GCC
NIX_LDFLAGS NIX_LDFLAGS
NIX_LDFLAGS_BEFORE NIX_LDFLAGS_BEFORE
NIX_DYNAMIC_LINKER
NIX_LDFLAGS_AFTER NIX_LDFLAGS_AFTER
NIX_LDFLAGS_HARDEN NIX_LDFLAGS_HARDEN
NIX_HARDENING_ENABLE NIX_HARDENING_ENABLE
@ -25,6 +26,10 @@ if [ -e @out@/nix-support/libc-ldflags ]; then
NIX_LDFLAGS_@suffixSalt@+=" $(< @out@/nix-support/libc-ldflags)" NIX_LDFLAGS_@suffixSalt@+=" $(< @out@/nix-support/libc-ldflags)"
fi fi
if [ -z "$NIX_DYNAMIC_LINKER_@suffixSalt@" ] && [ -e @out@/nix-support/ld-set-dynamic-linker ]; then
NIX_DYNAMIC_LINKER_@suffixSalt@="$(< @out@/nix-support/dynamic-linker)"
fi
if [ -e @out@/nix-support/libc-ldflags-before ]; then if [ -e @out@/nix-support/libc-ldflags-before ]; then
NIX_LDFLAGS_BEFORE_@suffixSalt@="$(< @out@/nix-support/libc-ldflags-before) $NIX_LDFLAGS_BEFORE_@suffixSalt@" NIX_LDFLAGS_BEFORE_@suffixSalt@="$(< @out@/nix-support/libc-ldflags-before) $NIX_LDFLAGS_BEFORE_@suffixSalt@"
fi fi

View File

@ -237,19 +237,14 @@ stdenv.mkDerivation {
if [ -n "''${dynamicLinker-}" ]; then if [ -n "''${dynamicLinker-}" ]; then
echo $dynamicLinker > $out/nix-support/dynamic-linker echo $dynamicLinker > $out/nix-support/dynamic-linker
'' + (if targetPlatform.isDarwin then '' ${if targetPlatform.isDarwin then ''
printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
'' else '' '' else ''
if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then
echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32 echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
fi fi
'' touch $out/nix-support/ld-set-dynamic-linker
# The dynamic linker is passed in `ldflagsBefore' to allow ''}
# explicit overrides of the dynamic linker by callers to ld
# (the *last* value counts, so ours should come first).
+ ''
echo -dynamic-linker "$dynamicLinker" >> $out/nix-support/libc-ldflags-before
'') + ''
fi fi
'') '')

View File

@ -20,6 +20,7 @@ if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
source @out@/nix-support/add-flags.sh source @out@/nix-support/add-flags.sh
fi fi
setDynamicLinker=1
# Optionally filter out paths not refering to the store. # Optionally filter out paths not refering to the store.
expandResponseParams "$@" expandResponseParams "$@"
@ -47,6 +48,11 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
# Our ld is not built with sysroot support (Can we fix that?) # Our ld is not built with sysroot support (Can we fix that?)
: :
else else
if [[ "$p" = -static || "$p" = -static-pie ]]; then
# Using a dynamic linker for static binaries can lead to crashes.
# This was observed for rust binaries.
setDynamicLinker=0
fi
rest+=("$p") rest+=("$p")
fi fi
n+=1 n+=1
@ -63,6 +69,11 @@ extraBefore=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"})
if [ -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ]; then if [ -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ]; then
extraAfter+=($NIX_LDFLAGS_@suffixSalt@) extraAfter+=($NIX_LDFLAGS_@suffixSalt@)
extraBefore+=($NIX_LDFLAGS_BEFORE_@suffixSalt@) extraBefore+=($NIX_LDFLAGS_BEFORE_@suffixSalt@)
# By adding dynamic linker to extraBefore we allow the users set their
# own dynamic linker as NIX_LD_FLAGS will override earlier set flags
if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
extraBefore+=("-dynamic-linker" "$NIX_DYNAMIC_LINKER_@suffixSalt@")
fi
fi fi
extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@) extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@)
@ -134,7 +145,7 @@ then
done done
fi fi
if [ -e "@out@/nix-support/dynamic-linker-m32" ] && (( "$link32" )); then if [[ "$link32" = "1" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynamic-linker-m32" ]]; then
# We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's # We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's
# use it. # use it.
extraAfter+=( extraAfter+=(

View File

@ -28,6 +28,7 @@ cc1=0
[[ "@prog@" = *++ ]] && isCpp=1 || isCpp=0 [[ "@prog@" = *++ ]] && isCpp=1 || isCpp=0
cppInclude=1 cppInclude=1
cInclude=1 cInclude=1
setDynamicLinker=1
expandResponseParams "$@" expandResponseParams "$@"
declare -i n=0 declare -i n=0
@ -58,6 +59,8 @@ while (( "$n" < "$nParams" )); do
cppInclude=0 cppInclude=0
elif [ "$p" = -nostdinc++ ]; then elif [ "$p" = -nostdinc++ ]; then
cppInclude=0 cppInclude=0
elif [[ "$p" = -static || "$p" = -static-pie ]]; then
setDynamicLinker=0
elif [[ "$p" != -?* ]]; then elif [[ "$p" != -?* ]]; then
# A dash alone signifies standard input; it is not a flag # A dash alone signifies standard input; it is not a flag
nonFlagArgs=1 nonFlagArgs=1
@ -152,6 +155,9 @@ if [ "$dontLink" != 1 ]; then
for i in $NIX_LDFLAGS_BEFORE_@suffixSalt@; do for i in $NIX_LDFLAGS_BEFORE_@suffixSalt@; do
extraBefore+=("-Wl,$i") extraBefore+=("-Wl,$i")
done done
if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
extraBefore+=("-Wl,-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")
fi
for i in $NIX_LDFLAGS_@suffixSalt@; do for i in $NIX_LDFLAGS_@suffixSalt@; do
if [ "${i:0:3}" = -L/ ]; then if [ "${i:0:3}" = -L/ ]; then
extraAfter+=("$i") extraAfter+=("$i")

View File

@ -37,6 +37,9 @@ if test "$noSysDirs" = "1"; then
# Figure out what extra flags when linking to pass to the gcc # Figure out what extra flags when linking to pass to the gcc
# compilers being generated to make sure that they use our libc. # compilers being generated to make sure that they use our libc.
extraLDFlags=($(< "${!curBintools}/nix-support/libc-ldflags") $(< "${!curBintools}/nix-support/libc-ldflags-before" || true)) extraLDFlags=($(< "${!curBintools}/nix-support/libc-ldflags") $(< "${!curBintools}/nix-support/libc-ldflags-before" || true))
if [ -e ${!curBintools}/nix-support/ld-set-dynamic-linker ]; then
extraLDFlags=-dynamic-linker=$(< ${!curBintools}/nix-support/dynamic-linker)
fi
# The path to the Libc binaries such as `crti.o'. # The path to the Libc binaries such as `crti.o'.
libc_libdir="$(< "${!curBintools}/nix-support/orig-libc")/lib" libc_libdir="$(< "${!curBintools}/nix-support/orig-libc")/lib"
@ -252,7 +255,7 @@ postInstall() {
if [[ targetConfig == *"linux"* ]]; then if [[ targetConfig == *"linux"* ]]; then
# For some reason, when building for linux on darwin, the libs retain # For some reason, when building for linux on darwin, the libs retain
# RPATH to $out. # RPATH to $out.
for i in "$lib"/"$targetConfig"/lib/{libtsan,libasan,libubsan}.so.*.*.*; do for i in "$lib"/"$targetConfig"/lib/{libtsan,libasan,libubsan}.so.*.*.*; do
PREV_RPATH=`patchelf --print-rpath "$i"` PREV_RPATH=`patchelf --print-rpath "$i"`
NEW_RPATH=`echo "$PREV_RPATH" | sed "s,:${out}[^:]*,,g"` NEW_RPATH=`echo "$PREV_RPATH" | sed "s,:${out}[^:]*,,g"`

View File

@ -1,11 +1,13 @@
{ stdenv }: { stdenv, glibc }:
with stdenv.lib; with stdenv.lib;
let let
# Sanitizers are not supported on Darwin. # Sanitizers are not supported on Darwin.
# Sanitizer headers aren't available in older libc++ stdenvs due to a bug # Sanitizer headers aren't available in older libc++ stdenvs due to a bug
sanitizersWorking = sanitizersWorking = !stdenv.hostPlatform.isMusl && (
(stdenv.cc.isClang && versionAtLeast (getVersion stdenv.cc.name) "5.0.0") (stdenv.cc.isClang && versionAtLeast (getVersion stdenv.cc.name) "5.0.0")
|| (stdenv.cc.isGNU && stdenv.isLinux); || (stdenv.cc.isGNU && stdenv.isLinux)
);
staticLibc = optionalString (stdenv.hostPlatform.libc == "glibc") "-L ${glibc.static}/lib";
in stdenv.mkDerivation { in stdenv.mkDerivation {
name = "cc-wrapper-test"; name = "cc-wrapper-test";
@ -28,6 +30,19 @@ in stdenv.mkDerivation {
./core-foundation-check ./core-foundation-check
''} ''}
${optionalString (!stdenv.isDarwin) ''
printf "checking whether compiler builds valid static C binaries... " >&2
$CC ${staticLibc} -static -o cc-static ${./cc-main.c}
./cc-static
# our glibc does not have pie enabled yet.
${optionalString (stdenv.hostPlatform.isMusl && stdenv.cc.isGNU) ''
printf "checking whether compiler builds valid static pie C binaries... " >&2
$CC ${staticLibc} -static-pie -o cc-static-pie ${./cc-main.c}
./cc-static-pie
''}
''}
printf "checking whether compiler uses NIX_CFLAGS_COMPILE... " >&2 printf "checking whether compiler uses NIX_CFLAGS_COMPILE... " >&2
mkdir -p foo/include mkdir -p foo/include
cp ${./foo.c} foo/include/foo.h cp ${./foo.c} foo/include/foo.h