From 3db93c351d221365556200d48d318a6f89c4339f Mon Sep 17 00:00:00 2001 From: Franz Pletz Date: Wed, 14 Feb 2024 09:30:45 +0100 Subject: [PATCH] cc-wrapper: add stack clash protection hardening flag Most Linux distributions are enabling this these days and it does protect against real world vulnerabilities as demonstrated by CVE-2018-16864 and CVE-2018-16865. Fix #53753. Information on llvm version support gleaned from https://github.com/llvm/llvm-project/commit/6609892a2dcdd1a4f6adefe191b55524861f020c https://github.com/llvm/llvm-project/commit/68e07da3e5d5175e24caa309e2b13cb333365c8c https://github.com/llvm/llvm-project/commit/092507a730fa4fad6dbe544cd139cfb7e8179aa4 Information on gcc version support a lot harder to gather, but both 32bit and 64bit arm do appear to be supported based on the test suite. --- .../build-support/cc-wrapper/add-hardening.sh | 6 ++++- pkgs/development/compilers/gcc/default.nix | 5 +++- .../compilers/llvm/common/clang/default.nix | 26 +++++++++++++------ pkgs/stdenv/darwin/default.nix | 6 ++++- pkgs/stdenv/generic/make-derivation.nix | 1 + pkgs/stdenv/linux/bootstrap-tools/default.nix | 7 ++++- pkgs/top-level/stage.nix | 1 + 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/pkgs/build-support/cc-wrapper/add-hardening.sh b/pkgs/build-support/cc-wrapper/add-hardening.sh index ef166e2f50c5..0dca3b3347e5 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 fortify3 stackprotector pie pic strictoverflow format trivialautovarinit zerocallusedregs) + declare -a allHardeningFlags=(fortify fortify3 stackprotector stackclashprotection pie pic strictoverflow format trivialautovarinit zerocallusedregs) declare -A hardeningDisableMap=() # Determine which flags were effectively disabled so we can report below. @@ -79,6 +79,10 @@ for flag in "${!hardeningEnableMap[@]}"; do if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling stackprotector >&2; fi hardeningCFlagsBefore+=('-fstack-protector-strong' '--param' 'ssp-buffer-size=4') ;; + stackclashprotection) + if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling stack-clash-protection >&2; fi + hardeningCFlagsBefore+=('-fstack-clash-protection') + ;; pie) # NB: we do not use `+=` here, because PIE flags must occur before any PIC flags if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling CFlags -fPIE >&2; fi diff --git a/pkgs/development/compilers/gcc/default.nix b/pkgs/development/compilers/gcc/default.nix index 5e017a21fa1f..5eb92fd701da 100644 --- a/pkgs/development/compilers/gcc/default.nix +++ b/pkgs/development/compilers/gcc/default.nix @@ -280,7 +280,7 @@ pipe ((callFile ./common/builder.nix {}) ({ libc_dev = stdenv.cc.libc_dev; - hardeningDisable = [ "format" "pie" ] + hardeningDisable = [ "format" "pie" "stackclashprotection" ] ++ optionals (is11 && langAda) [ "fortify3" ]; postPatch = optionalString atLeast7 '' @@ -425,6 +425,9 @@ pipe ((callFile ./common/builder.nix {}) ({ inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD langJava version; isGNU = true; hardeningUnsupportedFlags = optional is48 "stackprotector" + ++ optional ( + (targetPlatform.isAarch64 && !atLeast9) || !atLeast8 + ) "stackclashprotection" ++ optional (!atLeast11) "zerocallusedregs" ++ optionals (!atLeast12) [ "fortify3" "trivialautovarinit" ] ++ optionals (langFortran) [ "fortify" "format" ]; diff --git a/pkgs/development/compilers/llvm/common/clang/default.nix b/pkgs/development/compilers/llvm/common/clang/default.nix index 58af0340a139..202c626da89f 100644 --- a/pkgs/development/compilers/llvm/common/clang/default.nix +++ b/pkgs/development/compilers/llvm/common/clang/default.nix @@ -134,16 +134,26 @@ let passthru = { inherit libllvm; isClang = true; - } // (lib.optionalAttrs (lib.versionAtLeast release_version "15") { - hardeningUnsupportedFlags = [ - "fortify3" - ]; hardeningUnsupportedFlagsByTargetPlatform = targetPlatform: - lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs" + [ "fortify3" ] + ++ lib.optional ( + (lib.versionOlder release_version "11") + || (targetPlatform.isAarch64 && (lib.versionOlder release_version "18.1")) + || (targetPlatform.isFreeBSD && (lib.versionOlder release_version "15")) + || !(targetPlatform.isLinux || targetPlatform.isFreeBSD) + || !( + targetPlatform.isx86 + || targetPlatform.isPower64 + || targetPlatform.isS390x + || targetPlatform.isAarch64 + ) + ) "stackclashprotection" + ++ lib.optional ( + (lib.versionOlder release_version "15") + || !(targetPlatform.isx86_64 || targetPlatform.isAarch64) + ) "zerocallusedregs" ++ (finalAttrs.passthru.hardeningUnsupportedFlags or []); - }) // (lib.optionalAttrs (lib.versionOlder release_version "15") { - hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; - }); + }; meta = llvm_meta // { homepage = "https://clang.llvm.org/"; diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 45cc6742c720..787c48898ac6 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -327,7 +327,11 @@ in ''; passthru = { isFromBootstrapFiles = true; - hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; + hardeningUnsupportedFlags = [ + "fortify3" + "stackclashprotection" + "zerocallusedregs" + ]; }; }; clang-unwrapped = selfTools.libclang; diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index af68bf890ed2..f03c68a4c5cb 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -119,6 +119,7 @@ let "pie" "relro" "stackprotector" + "stackclashprotection" "strictoverflow" "trivialautovarinit" "zerocallusedregs" diff --git a/pkgs/stdenv/linux/bootstrap-tools/default.nix b/pkgs/stdenv/linux/bootstrap-tools/default.nix index 6d2490acfa47..4450679983ff 100644 --- a/pkgs/stdenv/linux/bootstrap-tools/default.nix +++ b/pkgs/stdenv/linux/bootstrap-tools/default.nix @@ -15,5 +15,10 @@ derivation ({ langC = true; langCC = true; isGNU = true; - hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" "trivialautovarinit" ]; + hardeningUnsupportedFlags = [ + "fortify3" + "stackclashprotection" + "trivialautovarinit" + "zerocallusedregs" + ]; } // extraAttrs) diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 390aa36db03b..b0c7ec03827b 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -292,6 +292,7 @@ let pkgsExtraHardening = super'; stdenv = super'.withDefaultHardeningFlags ( super'.stdenv.cc.defaultHardeningFlags ++ [ + "stackclashprotection" "trivialautovarinit" ] ) super'.stdenv;