Skip to content

Commit

Permalink
Merge pull request #259070 from risicle/ris-cc-default-hardening-flags
Browse files Browse the repository at this point in the history
mkDerivation, bintools-wrapper: move `defaultHardeningFlags` determination to `bintools-wrapper`
  • Loading branch information
risicle authored Dec 10, 2023
2 parents 9faaff8 + dc2247a commit aac4bc3
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 20 deletions.
25 changes: 25 additions & 0 deletions pkgs/build-support/bintools-wrapper/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
}:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 =
Expand Down
2 changes: 1 addition & 1 deletion pkgs/build-support/bintools-wrapper/setup-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pkgs/build-support/cc-wrapper/add-hardening.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions pkgs/build-support/cc-wrapper/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -271,6 +273,8 @@ stdenv.mkDerivation {
inherit expand-response-params;

inherit nixSupport;

inherit defaultHardeningFlags;
};

dontBuild = true;
Expand Down Expand Up @@ -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 =
Expand Down
3 changes: 1 addition & 2 deletions pkgs/build-support/cc-wrapper/fortran-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion pkgs/build-support/cc-wrapper/setup-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions pkgs/development/compilers/gcc/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions pkgs/stdenv/adapters.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
29 changes: 16 additions & 13 deletions pkgs/stdenv/generic/make-derivation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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';
Expand Down

0 comments on commit aac4bc3

Please sign in to comment.