diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 525b44fe04800..31be230a67ad0 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -33,6 +33,28 @@ , useMacosReexportHack ? false , wrapGas ? false +# Note: the hardening flags are part of the bintools-wrapper, rather than +# the cc-wrapper, because a few of them are handled by the linker. +, defaultHardeningFlags ? with stdenvNoCC; [ + "bindnow" + "format" + "fortify" + "fortify3" + "pic" + "relro" + "stackprotector" + "strictoverflow" + ] ++ lib.optional ( + # Musl-based platforms will keep "pie", other platforms will not. + # If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}` + # in the nixpkgs manual to inform users about the defaults. + targetPlatform.libc == "musl" + # Except when: + # - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries. + # - static armv7l, where compilation fails. + && !(hostPlatform.isAarch && hostPlatform.isStatic) + ) "pie" + # Darwin code signing support utilities , postLinkSignHook ? null, signingUtils ? null }: @@ -124,6 +146,8 @@ stdenv.mkDerivation { (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib64")))) '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)})) ''; + + inherit defaultHardeningFlags; }; dontBuild = true; @@ -380,6 +404,7 @@ stdenv.mkDerivation { wrapperName = "BINTOOLS_WRAPPER"; inherit dynamicLinker targetPrefix suffixSalt coreutils_bin; inherit bintools_bin libc_bin libc_dev libc_lib; + default_hardening_flags_str = builtins.toString defaultHardeningFlags; }; meta = diff --git a/pkgs/build-support/bintools-wrapper/setup-hook.sh b/pkgs/build-support/bintools-wrapper/setup-hook.sh index 7e9547b96c259..c146cbea80e4f 100644 --- a/pkgs/build-support/bintools-wrapper/setup-hook.sh +++ b/pkgs/build-support/bintools-wrapper/setup-hook.sh @@ -65,7 +65,7 @@ do done # If unset, assume the default hardening flags. -: ${NIX_HARDENING_ENABLE="fortify stackprotector pic strictoverflow format relro bindnow"} +: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"} export NIX_HARDENING_ENABLE # No local scope in sourced file diff --git a/pkgs/build-support/cc-wrapper/add-hardening.sh b/pkgs/build-support/cc-wrapper/add-hardening.sh index 8cd63e4609518..2eae278da1604 100644 --- a/pkgs/build-support/cc-wrapper/add-hardening.sh +++ b/pkgs/build-support/cc-wrapper/add-hardening.sh @@ -32,7 +32,7 @@ if [[ -n "${hardeningEnableMap[fortify3]-}" ]]; then fi if (( "${NIX_DEBUG:-0}" >= 1 )); then - declare -a allHardeningFlags=(fortify stackprotector pie pic strictoverflow format) + declare -a allHardeningFlags=(fortify fortify3 stackprotector pie pic strictoverflow format) declare -A hardeningDisableMap=() # Determine which flags were effectively disabled so we can report below. diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 539c29a0a7743..56075a032971c 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -218,6 +218,8 @@ let then guess else null; + defaultHardeningFlags = bintools.defaultHardeningFlags or []; + darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin ( if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx" else targetPlatform.darwinPlatform @@ -271,6 +273,8 @@ stdenv.mkDerivation { inherit expand-response-params; inherit nixSupport; + + inherit defaultHardeningFlags; }; dontBuild = true; @@ -706,6 +710,7 @@ stdenv.mkDerivation { inherit suffixSalt coreutils_bin bintools; inherit libc_bin libc_dev libc_lib; inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; + default_hardening_flags_str = builtins.toString defaultHardeningFlags; }; meta = diff --git a/pkgs/build-support/cc-wrapper/fortran-hook.sh b/pkgs/build-support/cc-wrapper/fortran-hook.sh index d72f314c01ce6..02da7fd0dc34c 100644 --- a/pkgs/build-support/cc-wrapper/fortran-hook.sh +++ b/pkgs/build-support/cc-wrapper/fortran-hook.sh @@ -4,8 +4,7 @@ getTargetRoleWrapper export FC${role_post}=@named_fc@ # If unset, assume the default hardening flags. -# These are different for fortran. -: ${NIX_HARDENING_ENABLE="stackprotector pic strictoverflow relro bindnow"} +: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"} export NIX_HARDENING_ENABLE unset -v role_post diff --git a/pkgs/build-support/cc-wrapper/setup-hook.sh b/pkgs/build-support/cc-wrapper/setup-hook.sh index 9326d76e2a8ff..33a2b62a49b00 100644 --- a/pkgs/build-support/cc-wrapper/setup-hook.sh +++ b/pkgs/build-support/cc-wrapper/setup-hook.sh @@ -111,7 +111,7 @@ export CC${role_post}=@named_cc@ export CXX${role_post}=@named_cxx@ # If unset, assume the default hardening flags. -: ${NIX_HARDENING_ENABLE="fortify fortify3 stackprotector pic strictoverflow format relro bindnow"} +: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"} export NIX_HARDENING_ENABLE # No local scope in sourced file diff --git a/pkgs/development/compilers/gcc/default.nix b/pkgs/development/compilers/gcc/default.nix index eef6faf26424e..e0ca04a138787 100644 --- a/pkgs/development/compilers/gcc/default.nix +++ b/pkgs/development/compilers/gcc/default.nix @@ -406,8 +406,9 @@ lib.pipe ((callFile ./common/builder.nix {}) ({ passthru = { inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD langJava version; isGNU = true; - } // lib.optionalAttrs (!atLeast12) { - hardeningUnsupportedFlags = lib.optionals is48 [ "stackprotector" ] ++ [ "fortify3" ]; + hardeningUnsupportedFlags = lib.optional is48 "stackprotector" + ++ lib.optional (!atLeast12) "fortify3" + ++ lib.optionals (langFortran) [ "fortify" "format" ]; }; enableParallelBuilding = true; diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix index dd29871907188..aeacf96443d03 100644 --- a/pkgs/stdenv/adapters.nix +++ b/pkgs/stdenv/adapters.nix @@ -417,4 +417,18 @@ rec { "propagatedBuildInputs" ]); }); + + withDefaultHardeningFlags = defaultHardeningFlags: stdenv: let + bintools = let + bintools' = stdenv.cc.bintools; + in if bintools' ? override then (bintools'.override { + inherit defaultHardeningFlags; + }) else bintools'; + in + stdenv.override (old: { + cc = if stdenv.cc == null then null else stdenv.cc.override { + inherit bintools; + }; + allowedRequisites = lib.mapNullable (rs: rs ++ [ bintools ]) (stdenv.allowedRequisites or null); + }); } diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index faa83507893f1..78e3f87daabe0 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -239,23 +239,26 @@ let # disabling fortify implies fortify3 should also be disabled then unique (hardeningDisable ++ [ "fortify3" ]) else hardeningDisable; - supportedHardeningFlags = [ "fortify" "fortify3" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ]; - # Musl-based platforms will keep "pie", other platforms will not. - # If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}` - # in the nixpkgs manual to inform users about the defaults. - defaultHardeningFlags = if stdenv.hostPlatform.isMusl && - # Except when: - # - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries. - # - static armv7l, where compilation fails. - !(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic) - then supportedHardeningFlags - else remove "pie" supportedHardeningFlags; + knownHardeningFlags = [ + "bindnow" + "format" + "fortify" + "fortify3" + "pic" + "pie" + "relro" + "stackprotector" + "strictoverflow" + ]; + defaultHardeningFlags = stdenv.cc.defaultHardeningFlags or + # fallback safe-ish set of flags + (remove "pie" knownHardeningFlags); enabledHardeningOptions = if builtins.elem "all" hardeningDisable' then [] else subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable); # hardeningDisable additionally supports "all". - erroneousHardeningFlags = subtractLists supportedHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable); + erroneousHardeningFlags = subtractLists knownHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable); checkDependencyList = checkDependencyList' []; checkDependencyList' = positions: name: deps: flip imap1 deps (index: dep: @@ -264,7 +267,7 @@ let else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}"); in if builtins.length erroneousHardeningFlags != 0 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} { - inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags; + inherit erroneousHardeningFlags hardeningDisable hardeningEnable knownHardeningFlags; }) else let doCheck = doCheck';