Merge pull request #259070 from risicle/ris-cc-default-hardening-flags

mkDerivation, bintools-wrapper: move `defaultHardeningFlags` determination to `bintools-wrapper`
This commit is contained in:
Robert Scott
2023-12-10 21:53:41 +00:00
committed by GitHub
9 changed files with 67 additions and 20 deletions

View File

@@ -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 =

View File

@@ -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

View File

@@ -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.

View File

@@ -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 =

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
});
}

View File

@@ -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';