From aaeeef5b6c7848a7569cb7a1f651550d0e5f8327 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sat, 2 Nov 2024 15:49:04 +0100 Subject: [PATCH] stdenv: fix custom hardening settings when using `__structuredAttrs = true;` Replaces / Closes #353131 A while ago `postgresql` switched to using structured attrs[1]. In the PR it was reported that this made postgresql notably slower when importing SQL dumps[2]. After a bit of debugging it turned out that the hardening was entirely missing and the following combination of settings was the culprit: hardeningEnable = [ "pie" ]; __structuredAttrs = true; I.e. the combination of custom hardening settings and structured attrs. What happened here is that internally the default and enabled hardening flags get written into `NIX_HARDENING_ENABLE`. However, the value is a list and the setting is not in the `env` section. This means that in the structured-attrs case we get something like declare -ax NIX_HARDENING_ENABLE=([0]="bindnow" [1]="format" [2]="fortify" [3]="fortify3" [4]="pic" [5]="relro" [6]="stackprotector" [7]="strictoverflow" [8]="zerocallusedregs" [9]="pie") i.e. an actual array rather than a string with all hardening flags being space-separated which is what the hardening code of the cc-wrapper expects[3]. This only happens if `hardeningEnable` or `hardeningDisable` are explicitly set by a derivation: if none of those are set, `NIX_HARDENING_ENABLE` won't be set by `stdenv.mkDerivation` and the default hardening flags are configured by the setup hook of the cc-wrapper[4]. In other words, this _only_ applies to derivations that have both custom hardening settings _and_ `__structuredAttrs = true;`. All values of `NIX_HARDENING_ENABLE` are well-known, so we don't have to worry about escaping issues. Just forcing it to a string by concatenating the list everytime solves the issue without additional issues like eval errors when inheriting `env` from a structuredAttrs derivation[5]. The price we're paying is a full rebuild. [1] https://github.com/NixOS/nixpkgs/pull/294504 [2] https://github.com/NixOS/nixpkgs/pull/294504#issuecomment-2451482522 [3] https://github.com/NixOS/nixpkgs/blob/cf3e5d3744dc26c3498aa5dadfa0e078c632cede/pkgs/build-support/cc-wrapper/add-hardening.sh#L9 [4] https://github.com/NixOS/nixpkgs/blob/cf3e5d3744dc26c3498aa5dadfa0e078c632cede/pkgs/build-support/cc-wrapper/setup-hook.sh#L114 [5] https://github.com/NixOS/nixpkgs/pull/353131/commits/1e84a7fb95ba8770aca373efd95d1dc87ceef432 --- pkgs/stdenv/generic/make-derivation.nix | 2 +- pkgs/test/cc-wrapper/hardening.nix | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index b2b6576c4acd..d4d5ee46638a 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -413,7 +413,7 @@ else let enableParallelChecking = attrs.enableParallelChecking or true; enableParallelInstalling = attrs.enableParallelInstalling or true; } // optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) { - NIX_HARDENING_ENABLE = enabledHardeningOptions; + NIX_HARDENING_ENABLE = builtins.concatStringsSep " " enabledHardeningOptions; } // optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) { requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ]; } // optionalAttrs (stdenv.buildPlatform.isDarwin) ( diff --git a/pkgs/test/cc-wrapper/hardening.nix b/pkgs/test/cc-wrapper/hardening.nix index 270e9a2e8761..fb30d17841e3 100644 --- a/pkgs/test/cc-wrapper/hardening.nix +++ b/pkgs/test/cc-wrapper/hardening.nix @@ -178,6 +178,13 @@ in nameDrvAfterAttrName ({ ignorePie = false; }); + pieExplicitEnabledStructuredAttrs = brokenIf stdenv.hostPlatform.isStatic (checkTestBin (f2exampleWithStdEnv stdenv { + hardeningEnable = [ "pie" ]; + __structuredAttrs = true; + }) { + ignorePie = false; + }); + relROExplicitEnabled = checkTestBin (f2exampleWithStdEnv stdenv { hardeningEnable = [ "relro" ]; }) {