From 40868719b0ff142d0df5fba0f2ec7f370e072048 Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Sun, 8 Oct 2023 22:56:46 +0100 Subject: [PATCH 1/4] cc-wrapper: add zerocallusedregs hardening flag this uses the value `used-gpr` which seems to be a commonly chosen value for general use --- nixos/doc/manual/release-notes/rl-2405.section.md | 2 ++ pkgs/build-support/cc-wrapper/add-hardening.sh | 6 +++++- pkgs/development/compilers/gcc/default.nix | 1 + pkgs/development/compilers/llvm/10/clang/default.nix | 2 +- pkgs/development/compilers/llvm/11/clang/default.nix | 2 +- pkgs/development/compilers/llvm/12/clang/default.nix | 2 +- pkgs/development/compilers/llvm/13/clang/default.nix | 2 +- pkgs/development/compilers/llvm/14/clang/default.nix | 2 +- pkgs/development/compilers/llvm/15/clang/default.nix | 6 +++++- pkgs/development/compilers/llvm/16/clang/default.nix | 6 +++++- pkgs/development/compilers/llvm/17/clang/default.nix | 6 +++++- pkgs/development/compilers/llvm/8/clang/default.nix | 2 +- pkgs/development/compilers/llvm/9/clang/default.nix | 2 +- pkgs/development/compilers/llvm/git/clang/default.nix | 6 +++++- pkgs/stdenv/darwin/default.nix | 5 ++++- pkgs/stdenv/generic/make-derivation.nix | 1 + pkgs/stdenv/linux/bootstrap-tools-musl/default.nix | 2 +- pkgs/stdenv/linux/bootstrap-tools/default.nix | 2 +- 18 files changed, 42 insertions(+), 15 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 0286b3346a65a..b6d5f02220d91 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -195,6 +195,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `stdenv`: The `--replace` flag in `substitute`, `substituteInPlace`, `substituteAll`, `substituteAllStream`, and `substituteStream` is now deprecated if favor of the new `--replace-fail`, `--replace-warn` and `--replace-quiet`. The deprecated `--replace` equates to `--replace-warn`. +- A new hardening flag, `zerocallusedregs` was made available, corresponding to the gcc/clang option `-fzero-call-used-regs=used-gpr`. + - The Yama LSM is now enabled by default in the kernel, which prevents ptracing non-child processes. This means you will not be able to attach gdb to an existing process, but will need to start that process from gdb (so it is a diff --git a/pkgs/build-support/cc-wrapper/add-hardening.sh b/pkgs/build-support/cc-wrapper/add-hardening.sh index 2eae278da1604..e884f8388b58b 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) + declare -a allHardeningFlags=(fortify fortify3 stackprotector pie pic strictoverflow format zerocallusedregs) declare -A hardeningDisableMap=() # Determine which flags were effectively disabled so we can report below. @@ -110,6 +110,10 @@ for flag in "${!hardeningEnableMap[@]}"; do if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling format >&2; fi hardeningCFlagsBefore+=('-Wformat' '-Wformat-security' '-Werror=format-security') ;; + zerocallusedregs) + if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling zerocallusedregs >&2; fi + hardeningCFlagsBefore+=('-fzero-call-used-regs=used-gpr') + ;; *) # Ignore unsupported. Checked in Nix that at least *some* # tool supports each flag. diff --git a/pkgs/development/compilers/gcc/default.nix b/pkgs/development/compilers/gcc/default.nix index e0ca04a138787..53bc057a5b253 100644 --- a/pkgs/development/compilers/gcc/default.nix +++ b/pkgs/development/compilers/gcc/default.nix @@ -407,6 +407,7 @@ lib.pipe ((callFile ./common/builder.nix {}) ({ inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD langJava version; isGNU = true; hardeningUnsupportedFlags = lib.optional is48 "stackprotector" + ++ lib.optional (!atLeast11) "zerocallusedregs" ++ lib.optional (!atLeast12) "fortify3" ++ lib.optionals (langFortran) [ "fortify" "format" ]; }; diff --git a/pkgs/development/compilers/llvm/10/clang/default.nix b/pkgs/development/compilers/llvm/10/clang/default.nix index ad4e913041583..747e7cf1a5516 100644 --- a/pkgs/development/compilers/llvm/10/clang/default.nix +++ b/pkgs/development/compilers/llvm/10/clang/default.nix @@ -90,7 +90,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/11/clang/default.nix b/pkgs/development/compilers/llvm/11/clang/default.nix index 0e61930f1c0e7..5ddecd1f47e90 100644 --- a/pkgs/development/compilers/llvm/11/clang/default.nix +++ b/pkgs/development/compilers/llvm/11/clang/default.nix @@ -95,7 +95,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/12/clang/default.nix b/pkgs/development/compilers/llvm/12/clang/default.nix index c46776d38ac3d..28f976a26bdb3 100644 --- a/pkgs/development/compilers/llvm/12/clang/default.nix +++ b/pkgs/development/compilers/llvm/12/clang/default.nix @@ -89,7 +89,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/13/clang/default.nix b/pkgs/development/compilers/llvm/13/clang/default.nix index 6604ae0efc3f1..7673c903e71cc 100644 --- a/pkgs/development/compilers/llvm/13/clang/default.nix +++ b/pkgs/development/compilers/llvm/13/clang/default.nix @@ -83,7 +83,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/14/clang/default.nix b/pkgs/development/compilers/llvm/14/clang/default.nix index 9f0da7a9f46cb..f63f55cfa5466 100644 --- a/pkgs/development/compilers/llvm/14/clang/default.nix +++ b/pkgs/development/compilers/llvm/14/clang/default.nix @@ -86,7 +86,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/15/clang/default.nix b/pkgs/development/compilers/llvm/15/clang/default.nix index c49d6368cb97c..8c19956a0bfe1 100644 --- a/pkgs/development/compilers/llvm/15/clang/default.nix +++ b/pkgs/development/compilers/llvm/15/clang/default.nix @@ -97,7 +97,11 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ + "fortify3" + # supported on x86_64/aarch64 only + "zerocallusedregs" + ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/16/clang/default.nix b/pkgs/development/compilers/llvm/16/clang/default.nix index 5f28e810f603f..4e260906a2c5e 100644 --- a/pkgs/development/compilers/llvm/16/clang/default.nix +++ b/pkgs/development/compilers/llvm/16/clang/default.nix @@ -91,7 +91,11 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ + "fortify3" + # supported on x86_64/aarch64 only + "zerocallusedregs" + ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/17/clang/default.nix b/pkgs/development/compilers/llvm/17/clang/default.nix index 3184437830a20..7b530e009de21 100644 --- a/pkgs/development/compilers/llvm/17/clang/default.nix +++ b/pkgs/development/compilers/llvm/17/clang/default.nix @@ -95,7 +95,11 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ + "fortify3" + # supported on x86_64/aarch64 only + "zerocallusedregs" + ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/8/clang/default.nix b/pkgs/development/compilers/llvm/8/clang/default.nix index 994f9bd967c41..36b09df19c689 100644 --- a/pkgs/development/compilers/llvm/8/clang/default.nix +++ b/pkgs/development/compilers/llvm/8/clang/default.nix @@ -102,7 +102,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/9/clang/default.nix b/pkgs/development/compilers/llvm/9/clang/default.nix index 75814fc11c481..e8a2a4bd0db19 100644 --- a/pkgs/development/compilers/llvm/9/clang/default.nix +++ b/pkgs/development/compilers/llvm/9/clang/default.nix @@ -97,7 +97,7 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/git/clang/default.nix b/pkgs/development/compilers/llvm/git/clang/default.nix index d8fe08569f3f7..b8e5c4eb5910a 100644 --- a/pkgs/development/compilers/llvm/git/clang/default.nix +++ b/pkgs/development/compilers/llvm/git/clang/default.nix @@ -95,7 +95,11 @@ let passthru = { inherit libllvm; isClang = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ + "fortify3" + # supported on x86_64/aarch64 only + "zerocallusedregs" + ]; }; meta = llvm_meta // { diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index c94c56daae1c2..eb5403860cad5 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -341,7 +341,10 @@ in ln -s ${bootstrapTools}/lib/clang $out/lib ln -s ${bootstrapTools}/include $out ''; - passthru.isFromBootstrapFiles = true; + passthru = { + isFromBootstrapFiles = true; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; + }; }; clang-unwrapped = selfTools.libclang; libllvm = self.stdenv.mkDerivation { diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index cb1607c5e63aa..54a03a56866b5 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -249,6 +249,7 @@ let "relro" "stackprotector" "strictoverflow" + "zerocallusedregs" ]; defaultHardeningFlags = (if stdenv.hasCC then stdenv.cc else {}).defaultHardeningFlags or diff --git a/pkgs/stdenv/linux/bootstrap-tools-musl/default.nix b/pkgs/stdenv/linux/bootstrap-tools-musl/default.nix index 569f0c6f31e2f..ad2449cfd9ff7 100644 --- a/pkgs/stdenv/linux/bootstrap-tools-musl/default.nix +++ b/pkgs/stdenv/linux/bootstrap-tools-musl/default.nix @@ -15,5 +15,5 @@ derivation ({ langC = true; langCC = true; isGNU = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; } // extraAttrs) diff --git a/pkgs/stdenv/linux/bootstrap-tools/default.nix b/pkgs/stdenv/linux/bootstrap-tools/default.nix index 569f0c6f31e2f..ad2449cfd9ff7 100644 --- a/pkgs/stdenv/linux/bootstrap-tools/default.nix +++ b/pkgs/stdenv/linux/bootstrap-tools/default.nix @@ -15,5 +15,5 @@ derivation ({ langC = true; langCC = true; isGNU = true; - hardeningUnsupportedFlags = [ "fortify3" ]; + hardeningUnsupportedFlags = [ "fortify3" "zerocallusedregs" ]; } // extraAttrs) From a1f94ed17882370ce8e06d78c37cc921b1efda0d Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Mon, 11 Dec 2023 18:01:24 +0000 Subject: [PATCH 2/4] add pkgsExtraHardening package set this package set can be used to trial new hardening flags or enable those which are still known to cause some problems --- nixos/doc/manual/release-notes/rl-2405.section.md | 2 ++ pkgs/top-level/stage.nix | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index b6d5f02220d91..74d47fb566041 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -214,6 +214,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [](#opt-boot.kernel.sysctl._net.core.wmem_max_) changed from a string to an integer because of the addition of a custom merge option (taking the highest value defined to avoid conflicts between 2 services trying to set that value), just as [](#opt-boot.kernel.sysctl._net.core.rmem_max_) since 22.11. +- A new top-level package set, `pkgsExtraHardening` is added. This is a set of packages built with stricter hardening flags - those that have not yet received enough testing to be applied universally, those that are more likely to cause build failures or those that have drawbacks to their use (e.g. performance or required hardware features). + - `services.zfs.zed.enableMail` now uses the global `sendmail` wrapper defined by an email module (such as msmtp or Postfix). It no longer requires using a special ZFS build with email support. diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 1cc05167cee83..cbf0f585fe411 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -276,6 +276,19 @@ let gcc.abi = "elfv2"; }; }); + + pkgsExtraHardening = nixpkgsFun { + overlays = [ + (self': super': { + pkgsExtraHardening = super'; + stdenv = super'.withDefaultHardeningFlags ( + super'.stdenv.cc.defaultHardeningFlags ++ [ + "zerocallusedregs" + ] + ) super'.stdenv; + }) + ] ++ overlays; + }; }; # The complete chain of package set builders, applied from top to bottom. From a938efebdab236cc4a17220f45cfd0b2e9b9f91c Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Sun, 17 Dec 2023 14:04:44 +0000 Subject: [PATCH 3/4] [dontmerge: amended to change sha] cc-wrapper, clang: use new mechanism to selectively unsupport zerocallusedregs this allows a compiler derivation to provide a hardeningUnsupportedFlagsByTargetPlatform passthru attr that will be called with the targetPlatform to determine the unsupported hardening flags for that platform. we can do this because even though a clang compiler is multi-target by nature, cc-wrapper effectively fixes the target platform at wrapping time. otherwise we'd have to sniff the intended target at runtime, which wouldn't be fun at all. the advantage of using a new attribute instead of allowing hardeningUnsupportedFlags to optionally be a function is that hardeningUnsupportedFlags retains its simple overriding pattern for simple cases (i.e. `(prev.hardeningUnsupportedFlags or []) ++ [ "foo" ]` ) which will continue to work as long as the bottom-most function of hardeningUnsupportedFlagsByTargetPlatform falls back to hardeningUnsupportedFlags. --- pkgs/build-support/cc-wrapper/default.nix | 11 ++++++++++- pkgs/development/compilers/llvm/15/clang/default.nix | 7 ++++--- pkgs/development/compilers/llvm/16/clang/default.nix | 7 ++++--- pkgs/development/compilers/llvm/17/clang/default.nix | 7 ++++--- pkgs/development/compilers/llvm/git/clang/default.nix | 7 ++++--- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 59aaa41e9c173..693c6e6fcfd49 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -223,6 +223,15 @@ let defaultHardeningFlags = bintools.defaultHardeningFlags or []; + # if cc.hardeningUnsupportedFlagsByTargetPlatform exists, this is + # called with the targetPlatform as an argument and + # cc.hardeningUnsupportedFlags is completely ignored - the function + # is responsible for including the constant hardeningUnsupportedFlags + # list however it sees fit. + ccHardeningUnsupportedFlags = if cc ? hardeningUnsupportedFlagsByTargetPlatform + then cc.hardeningUnsupportedFlagsByTargetPlatform targetPlatform + else (cc.hardeningUnsupportedFlags or []); + darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin ( if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx" else targetPlatform.darwinPlatform @@ -584,7 +593,7 @@ stdenv.mkDerivation { ## Hardening support ## + '' - export hardening_unsupported_flags="${builtins.concatStringsSep " " (cc.hardeningUnsupportedFlags or [])}" + export hardening_unsupported_flags="${builtins.concatStringsSep " " ccHardeningUnsupportedFlags}" '' # Machine flags. These are necessary to support diff --git a/pkgs/development/compilers/llvm/15/clang/default.nix b/pkgs/development/compilers/llvm/15/clang/default.nix index 8c19956a0bfe1..9ec15a3930040 100644 --- a/pkgs/development/compilers/llvm/15/clang/default.nix +++ b/pkgs/development/compilers/llvm/15/clang/default.nix @@ -7,7 +7,7 @@ }: let - self = stdenv.mkDerivation (rec { + self = stdenv.mkDerivation (finalAttrs: rec { pname = "clang"; inherit version; @@ -99,9 +99,10 @@ let isClang = true; hardeningUnsupportedFlags = [ "fortify3" - # supported on x86_64/aarch64 only - "zerocallusedregs" ]; + hardeningUnsupportedFlagsByTargetPlatform = targetPlatform: + lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs" + ++ (finalAttrs.passthru.hardeningUnsupportedFlags or []); }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/16/clang/default.nix b/pkgs/development/compilers/llvm/16/clang/default.nix index 4e260906a2c5e..43c497b927615 100644 --- a/pkgs/development/compilers/llvm/16/clang/default.nix +++ b/pkgs/development/compilers/llvm/16/clang/default.nix @@ -7,7 +7,7 @@ }: let - self = stdenv.mkDerivation (rec { + self = stdenv.mkDerivation (finalAttrs: rec { pname = "clang"; inherit version; @@ -93,9 +93,10 @@ let isClang = true; hardeningUnsupportedFlags = [ "fortify3" - # supported on x86_64/aarch64 only - "zerocallusedregs" ]; + hardeningUnsupportedFlagsByTargetPlatform = targetPlatform: + lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs" + ++ (finalAttrs.passthru.hardeningUnsupportedFlags or []); }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/17/clang/default.nix b/pkgs/development/compilers/llvm/17/clang/default.nix index 7b530e009de21..f2f114233c283 100644 --- a/pkgs/development/compilers/llvm/17/clang/default.nix +++ b/pkgs/development/compilers/llvm/17/clang/default.nix @@ -7,7 +7,7 @@ }: let - self = stdenv.mkDerivation (rec { + self = stdenv.mkDerivation (finalAttrs: rec { pname = "clang"; inherit version; @@ -97,9 +97,10 @@ let isClang = true; hardeningUnsupportedFlags = [ "fortify3" - # supported on x86_64/aarch64 only - "zerocallusedregs" ]; + hardeningUnsupportedFlagsByTargetPlatform = targetPlatform: + lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs" + ++ (finalAttrs.passthru.hardeningUnsupportedFlags or []); }; meta = llvm_meta // { diff --git a/pkgs/development/compilers/llvm/git/clang/default.nix b/pkgs/development/compilers/llvm/git/clang/default.nix index b8e5c4eb5910a..7d0dc964a9e4e 100644 --- a/pkgs/development/compilers/llvm/git/clang/default.nix +++ b/pkgs/development/compilers/llvm/git/clang/default.nix @@ -7,7 +7,7 @@ }: let - self = stdenv.mkDerivation (rec { + self = stdenv.mkDerivation (finalAttrs: rec { pname = "clang"; inherit version; @@ -97,9 +97,10 @@ let isClang = true; hardeningUnsupportedFlags = [ "fortify3" - # supported on x86_64/aarch64 only - "zerocallusedregs" ]; + hardeningUnsupportedFlagsByTargetPlatform = targetPlatform: + lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs" + ++ (finalAttrs.passthru.hardeningUnsupportedFlags or []); }; meta = llvm_meta // { From 91101d5b8445a61175f3a42a0b1090f67b64aacb Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Sat, 20 Jan 2024 19:31:38 -0800 Subject: [PATCH 4/4] WIP: skip extrahardening package set --- pkgs/top-level/release-attrpaths-superset.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/top-level/release-attrpaths-superset.nix b/pkgs/top-level/release-attrpaths-superset.nix index 673b63a5ac34f..55cce6101d71a 100644 --- a/pkgs/top-level/release-attrpaths-superset.nix +++ b/pkgs/top-level/release-attrpaths-superset.nix @@ -53,6 +53,7 @@ let pkgsStatic = true; pkgsCross = true; pkgsi686Linux = true; + pkgsExtraHardening = true; }; # No release package attrname may have any of these at a component