diff --git a/pkgs/build-support/bintools-wrapper/add-hardening.sh b/pkgs/build-support/bintools-wrapper/add-hardening.sh index 5282d17fce2..0f62aa49542 100644 --- a/pkgs/build-support/bintools-wrapper/add-hardening.sh +++ b/pkgs/build-support/bintools-wrapper/add-hardening.sh @@ -1,33 +1,45 @@ -hardeningFlags=(relro bindnow) -# Intentionally word-split in case 'hardeningEnable' is defined in -# Nix. Also, our bootstrap tools version of bash is old enough that -# undefined arrays trip `set -u`. -if [[ -v hardeningEnable[@] ]]; then - hardeningFlags+=(${hardeningEnable[@]}) +allHardeningFlags=(pie relro bindnow) +hardeningFlags=() + +declare -A hardeningEnableMap=() + +# Intentionally word-split in case 'NIX_HARDENING_ENABLE' is defined in Nix. The +# array expansion also prevents undefined variables from causing trouble with +# `set -u`. +for flag in ${NIX_@infixSalt@_HARDENING_ENABLE-}; do + hardeningEnableMap[$flag]=1 +done + +# Remove unsupported flags. +if (( "${NIX_DEBUG:-0}" >= 1 )); then + declare -A hardeningDisableMap=() fi -hardeningLDFlags=() - -declare -A hardeningDisableMap - -# Intentionally word-split in case 'hardeningDisable' is defined in Nix. -for flag in ${hardeningDisable[@]:-IGNORED_KEY} @hardening_unsupported_flags@ -do - hardeningDisableMap[$flag]=1 +for flag in @hardening_unsupported_flags@; do + [[ -n ${hardeningEnableMap[$flag]} ]] || continue + if (( "${NIX_DEBUG:-0}" >= 1 )); then + hardeningDisableMap[$flag]=1 + fi + unset hardeningEnableMap[$flag] done if (( "${NIX_DEBUG:-0}" >= 1 )); then + # Determine which flags were effectively disabled so we can report below. + for flag in ${allHardeningFlags[@]}; do + if [[ -z "${hardeningEnableMap[$flag]-}" ]]; then + hardeningDisableMap[$flag]=1 + fi + done + printf 'HARDENING: disabled flags:' >&2 (( "${#hardeningDisableMap[@]}" )) && printf ' %q' "${!hardeningDisableMap[@]}" >&2 echo >&2 fi -if [[ -z "${hardeningDisableMap[all]:-}" ]]; then +if (( "${#hardeningEnableMap[@]}" )); then if (( "${NIX_DEBUG:-0}" >= 1 )); then echo 'HARDENING: Is active (not completely disabled with "all" flag)' >&2; fi - for flag in "${hardeningFlags[@]}" - do - if [[ -z "${hardeningDisableMap[$flag]:-}" ]]; then + for flag in "${!hardeningEnableMap[@]}"; do case $flag in pie) if [[ ! ("$*" =~ " -shared " || "$*" =~ " -static ") ]]; then @@ -48,6 +60,5 @@ if [[ -z "${hardeningDisableMap[all]:-}" ]]; then # tool supports each flag. ;; esac - fi done fi diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index bbab9a6b71d..672a3dcbe38 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -58,7 +58,7 @@ fi source @out@/nix-support/add-hardening.sh extraAfter=() -extraBefore=("${hardeningLDFlags[@]}") +extraBefore=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"}) if [ -z "${NIX_@infixSalt@_LDFLAGS_SET:-}" ]; then extraAfter+=($NIX_@infixSalt@_LDFLAGS) diff --git a/pkgs/build-support/bintools-wrapper/setup-hook.sh b/pkgs/build-support/bintools-wrapper/setup-hook.sh index 48a00b0b9b0..831ee9b0387 100644 --- a/pkgs/build-support/bintools-wrapper/setup-hook.sh +++ b/pkgs/build-support/bintools-wrapper/setup-hook.sh @@ -83,6 +83,10 @@ do fi done +# If unset, assume the default hardening flags. +: ${NIX_HARDENING_ENABLE="fortify stackprotector pic strictoverflow format relro bindnow"} +export NIX_HARDENING_ENABLE + # No local scope in sourced file unset -v role_pre role_post cmd upper_case set +u diff --git a/pkgs/build-support/cc-wrapper/add-hardening.sh b/pkgs/build-support/cc-wrapper/add-hardening.sh index de5eb2506a8..0b483c12e84 100644 --- a/pkgs/build-support/cc-wrapper/add-hardening.sh +++ b/pkgs/build-support/cc-wrapper/add-hardening.sh @@ -1,4 +1,4 @@ -allHardeningFlags=(fortify stackprotector pie pic strictoverflow format relro bindnow) +allHardeningFlags=(fortify stackprotector pie pic strictoverflow format) hardeningCFlags=() declare -A hardeningEnableMap=() @@ -12,7 +12,7 @@ done # Remove unsupported flags. if (( "${NIX_DEBUG:-0}" >= 1 )); then - declare -A hardeningDisableMap=() + declare -A hardeningDisableMap=() fi for flag in @hardening_unsupported_flags@; do [[ -n ${hardeningEnableMap[$flag]} ]] || continue diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh index 15118d99db7..8a3cfb694b4 100644 --- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh +++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh @@ -135,7 +135,6 @@ source @out@/nix-support/add-hardening.sh # Add the flags for the C compiler proper. extraAfter=($NIX_@infixSalt@_CFLAGS_COMPILE) - extraBefore=(${hardeningCFlags[@]+"${hardeningCFlags[@]}"}) if [ "$dontLink" != 1 ]; then diff --git a/pkgs/build-support/cc-wrapper/setup-hook.sh b/pkgs/build-support/cc-wrapper/setup-hook.sh index 29a7306b9b7..15b84dca279 100644 --- a/pkgs/build-support/cc-wrapper/setup-hook.sh +++ b/pkgs/build-support/cc-wrapper/setup-hook.sh @@ -147,6 +147,10 @@ export ${role_pre}CXX=@named_cxx@ export CC${role_post}=@named_cc@ export CXX${role_post}=@named_cxx@ +# If unset, assume the default hardening flags. +: ${NIX_HARDENING_ENABLE="fortify stackprotector pic strictoverflow format relro bindnow"} +export NIX_HARDENING_ENABLE + # No local scope in sourced file unset -v role_pre role_post set +u diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index be98dee01ab..6f3896b4906 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -74,6 +74,11 @@ rec { # TODO(@Ericson2314): Make this more modular, and not O(n^2). let supportedHardeningFlags = [ "fortify" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ]; + defaultHardeningFlags = lib.remove "pie" supportedHardeningFlags; + enabledHardeningOptions = + if builtins.elem "all" hardeningDisable + then [] + else lib.subtractLists hardeningDisable (defaultHardeningFlags ++ hardeningEnable); # hardeningDisable additionally supports "all". erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable); in if builtins.length erroneousHardeningFlags != 0 @@ -115,19 +120,6 @@ rec { ] ]; - defaultHardeningFlags = [ - "fortify" "stackprotector" "pic" "strictoverflow" "format" "relro" "bindnow" - ]; - - hardeningDisable = lib.toList (attrs.hardeningDisable or [ ]); - - hardeningEnable = lib.toList (attrs.hardeningEnable or [ ]); - - enabledHardeningOptions = - if builtins.elem "all" hardeningDisable - then [] - else lib.subtractLists hardeningDisable (defaultHardeningFlags ++ hardeningEnable); - outputs' = outputs ++ (if separateDebugInfo then assert stdenv.hostPlatform.isLinux; [ "debug" ] else []); diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index 62bc2c2af6f..5f3808e9588 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -7,10 +7,6 @@ fi : ${outputs:=out} -# If unset, assume the default hardening flags. -: ${NIX_HARDENING_ENABLE="fortify stackprotector pic strictoverflow format relro bindnow"} -export NIX_HARDENING_ENABLE - ###################################################################### # Hook handling.