-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stdenv: fix hardeningEnable
with __structuredAttrs = true;
#353131
Conversation
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;`. I figured that it's far easier to just write a space-separated string for NIX_HARDENING_ENABLE into `env` if needed rather than changing the code in `add-hardening.sh` which would've caused a full rebuild. The flags are well-known identifiers anyways, so there's no risk of issues coming from missing escapes. [1] NixOS#294504 [2] NixOS#294504 (comment) [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
inherit erroneousHardeningFlags hardeningDisable hardeningEnable knownHardeningFlags; | ||
}) | ||
else let | ||
in let |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually needed to prevent an infinite recursion.
@@ -134,6 +134,7 @@ let | |||
"__darwinAllowLocalNetworking" | |||
"__impureHostDeps" "__propagatedImpureHostDeps" | |||
"sandboxProfile" "propagatedSandboxProfile" | |||
"enabledHardeningOptions" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty nasty because it removes each enabledHardeningOptions
set in a call to stdenv.mkDerivation
.
Any suggestions on how to improve that?
Hm. We have an ongoing effort for a few months now to try to make as much of the bash code work with both structuredAttrs on and off - without putting structuredAttrs checks all over the place. Started in #318614, tracked in #205690. I can't say anything about the timeline and the feasibility of a full rebuild right now, but we should consider how to solve it without putting those checks in various places and rather make the code using work with strings and arrays alike. |
The `env` gets inherited from a derivation using structured attrs, i.e. it also contains `NIX_HARDENING_ENABLE`. If this is not set, `stdenv.mkDerivation` will set `NIX_HARDENING_ENABLE` right into the derivation causing the evaluation to fail since there's now an overlap between with `env`: error: The `env` attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: - NIX_HARDENING_ENABLE: in `env`: "bindnow format pic relro stackprotector strictoverflow zerocallusedregs"; in derivation arguments: [ "bindnow" "format" "pic" "relro" "stackprotector" "strictoverflow" "zerocallusedregs" ]
(FWIW I would love it if we could turn structured attributes on by default for 25.05! Though it’s not the kind of thing we should do late in the cycle, so it’s fine if it slips.) Edit: Ah, though I guess this is just about a |
We have this case 4 times on master currently:
The case for postgresql was introduced in this cycle and is understood, but we'll need to look at the other cases. Seems like the respective hardening settings should not take effect right now as well? |
Will that be still in 24.11 then? I think we want to avoid a performance regression for PostgreSQL for the release. |
So, my gut feeling is that with this being effectively a release blocker and an approach existing to solve this without a full rebuild, I think we should go that way (unless the RMs are sure that a full rebuild is OK and are willing to delay the release if it doesn't work out -- but the state postgresql is currently in is not acceptable for a stable release IMHO). That said, see 1e84a7f for even more shortcomings. I'm willing to follow up with a changes in the bash code and a revert of the Nix changes after branch-off[1].
I think missing compiler hardenings is also a big no no.
As long as we're willing to delay 24.11 if we get delays in stabilizing staging, I'm fine with that as well. [1] I've been helping with earlier __structuredAttrs efforts already, so good to see that there's a tracking issue - I guess I may take a look if I can help. |
The |
OK, great. Already prepared a change for this that only touches |
Can you open a draft PR with that already? I think we might need to look at all places where |
Alternative to NixOS#353131
Alternative to NixOS#353131
Opened #353142. Was a good idea to do so, while preparing the commit I realized that I messed up the |
Broadly seems sensible to me. One thing I think I've missed is the reason for exposing Also if we were going to allow caller-specified (or am I totally misinterpreting the impact of adding it to |
Couldn't this be achieved by simply unconditionally manually converting |
So essentially this PR minus the
(and then remove the other Yeah, that should work as well, I guess?
Well, the idea would be to avoid checks in bash scripts, too, see discussion in #353142. But treating |
AFAIU Anyways, I think there's consensus to try a different approach. I think that your suggestion with just concatenating |
# hardeningDisable additionally supports "all". | ||
erroneousHardeningFlags = subtractLists knownHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable); | ||
|
||
env = (attrs.env or {}) // lib.optionalAttrs __structuredAttrs { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
running nixpkgs-review
at /home/kirillvr/.cache/nixpkgs-review/pr-353131/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:554:27:
553|
554| env = (attrs.env or {}) // lib.optionalAttrs __structuredAttrs {
| ^
555| NIX_HARDENING_ENABLE = builtins.concatStringsSep " " enabledHardeningOptions;
error: expected a set but found a string with context: "/nix/store/7awmks5w8v9yjgqbpmv3qa79k2qqg52i-wee-slack-env/lib/python3.12/site-packages"
@Ma27 this indeed fixes regression in postgresql ! |
… true;` Replaces / Closes NixOS#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] NixOS#294504 [2] NixOS#294504 (comment) [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] NixOS@1e84a7f
Let's move the discussion to #353142: just pushed a way easier version there that also passes the hardening test-case I wrote and doesn't have the issues we've seen here (at the cost of a full rebuild). |
Closing in favor of #353142. |
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:
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 likei.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
orhardeningDisable
are explicitly set by a derivation: if none of those are set,NIX_HARDENING_ENABLE
won't be set bystdenv.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;
.I figured that it's far easier to just write a space-separated string for NIX_HARDENING_ENABLE into
env
if needed rather than changing the code inadd-hardening.sh
which would've caused a full rebuild. The flags are well-known identifiers anyways, so there's no risk of issues coming from missing escapes.[1] #294504
[2] #294504 (comment)
[3]
nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
Line 9 in cf3e5d3
[4]
nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
Line 114 in cf3e5d3
cc @kirillrdy for me, the postgresql from this branch looks better. Can you confirm that your issue is resolved?
cc @NixOS/nixos-release-managers I'm pretty sure this is a blocker for 24.11.
cc @NixOS/security
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.