-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
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
mkDerivation, bintools-wrapper: move defaultHardeningFlags
determination to bintools-wrapper
#259070
mkDerivation, bintools-wrapper: move defaultHardeningFlags
determination to bintools-wrapper
#259070
Conversation
Is there any advantage to keeping defaults that get used in the build-support scripts when NIX_HARDENING_ENABLE is unset rather than unconditionally setting it? Seems more complicated substituting it into them like this. |
@ofborg build stdenv.cc bash |
Looks like mismatched defaults are still sneaking through in |
🤔 Defaults need to exist at some level (even if those defaults are "empty"). And remember, the cc & bintools wrappers don't just get used via
Damn that complicates things. |
So we have to substitute in to keep them in sync for usage in shells rather than package builds because otherwise those would have no default at all, got it. I still think we should unconditionally set NIX_HARDENING_ENABLE in stdenv.mkDerivation on top of this change that substitutes in the correct defaults. |
This is a problem for your PR too, because having an always-set |
I think the only one is that it allows the set of default hardening flags to be different for fortran, but this of course falls apart the second someone sets e.g. |
It looks to me like what they really wanted to do was filter out From all I can find, |
It looks like filtering out the flags from NIX_HARDENING_ENABLE means having fortran and c builds in the same shell will make the c build less secure, so it seems incorrect to do that too. Would it make sense to filter out incompatible flags for a particular language at the point of use instead? edit: I'm struggling to understand how the hardening flags work with fortran. add-hardening.sh adds the flags to hardeningCFlagsBefore/After. cc-wrapper.sh then uses those in the actual compiler call. Do gfortan calls still go through cc-wrapper.sh? Can we tell at the right point if a particular invocation is for fortran and remove incompatible flags there? |
#92412 (comment) - so let's test blas / lapack cross-compile |
Yeah I was too.
Yes looks like it :)
Maybe. I think at this point it's a matter of seeing which is the least-ugly option. Then there is of course the |
6606a10
to
76f7703
Compare
inherit expand-response-params; | ||
|
||
inherit nixSupport; | ||
|
||
inherit defaultHardeningFlags; |
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.
inherit expand-response-params; | |
inherit nixSupport; | |
inherit defaultHardeningFlags; | |
inherit expand-response-params nixSupport defaultHardeningFlags; |
nit
!(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic) | ||
then supportedHardeningFlags | ||
else lib.remove "pie" supportedHardeningFlags; | ||
knownHardeningFlags = [ |
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.
knownHardeningFlags = [ | |
// when updating consider update the default list in bintoos-wrapper | |
knownHardeningFlags = [ |
or similar
!(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic) | ||
then supportedHardeningFlags | ||
else lib.remove "pie" supportedHardeningFlags; | ||
knownHardeningFlags = [ |
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.
While we're at it, maybe we could also extract hardcoded constants in add-hardening.sh?
declare -a allHardeningFlags=(fortify stackprotector pie pic strictoverflow format) |
declare -a allHardeningFlags=(pie relro bindnow) |
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.
Flippin heck I forgot about those.
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.
Honestly think this is too tricky to do without introducing a bizarre two-way dependency between mkDerivation
and the wrappers. And attempting to bring the knownHardeningFlags
into the wrappers alongside defaultHardeningFlags
causes all sorts of problems around bootstrapping and use of unwrapped compilers/binutils because all of a sudden mkDerivation
has an empty knownHardeningFlags
which causes it to throw errors if any derivation happens to use hardeningDisable
or hardeningEnable
.
76f7703
to
52b481a
Compare
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.
While most hardening flags are arguably more of a c-compiler thing, it works better to put them in bintools-wrapper
I'm okay with this if there are any (even just one) hardening flags that are passed to the linker rather than the c-compiler. Is there such a flag?
If the linker really handles zero hardening flags, and is unlikely to handle any in the future, then I think the bintools-wrapper is a pretty unintuitive place to stash this default.
because cc-wrapper can easily refer to bintools but not vice-versa.
Why not make it a top-level non-derivation attribute in the packageset like pkgs.default-gcc-version
? Then it can be overridden with a simple overlay rather than having to build a whole new stdenv.
See also my comment below; even if we keep the defaultHardeningFlags in the bintools-wrapper we should make sure the defaulting logic happens in Nix rather than bash so you can change the defaults without rebuilding gcc
.
There are three already and likely more to come.
It doesn't feel like there's a huge amount of prior art for polluting |
8354218
to
49bb1b7
Compare
Thanks for the reviews - my instinct is that it's too close to the release to merge kind of change but I don't know what others think. |
I say go for it, and tell @vcunat that if it causes problems just revert it (i.e. if it does cause problems it isn't worth spending significant amount of time to fix them). |
I wouldn't merge it for 23.11 (anymore). Certainly not with the only argument that we can revert. There are reasons why we have merging restrictions #258640 (comment) |
This is not a breaking change. But waiting until after 23.11 is fine too. |
@@ -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) |
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.
is relro
not here on purpose?
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.
That is a very good question. It predates me, but it's also missing bindnow
so presumably this debug statement was meant to only print the cc-wrapper-related flags and not the bintools ones?
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.
BTW it would be awesome if this list of flags could be changed without causing rebuilds for NIX_DEBUG=0
(which is the default).
Edit: nevermind, this is cc-wrapper
, I thought it was bintools-wrapper
. I'm working on a PR which will accomplish this.
Now that staging is branched off we should merge this. Are there any objections? |
I'd prefer to wait for the dust to settle a bit more after the release (and for this have more of my attention in case it causes any fallout) |
…ion to bintools-wrapper this makes it a lot easier to create a modified stdenv with a different set of defaultHardeningFlags and as a bonus allows us to inject the correct defaultHardeningFlags into toolchain wrapper scripts, reducing repetition. while most hardening flags are arguably more of a compiler thing, it works better to put them in bintools-wrapper because cc-wrapper can easily refer to bintools but not vice-versa. mkDerivation can still easily refer to either when it is constructed. this also switches fortran-hook.sh to use the same defaults for NIX_HARDENING_ENABLE as for C. previously NIX_HARDENING_ENABLE defaults were apparently used to avoid passing problematic flags to a fortran compiler, but this falls apart as soon as mkDerivation sets its own NIX_HARDENING_ENABLE - cc.hardeningUnsupportedFlags is a more appropriate mechanism for this as it actively filters out flags from being used by the wrapper, so switch to using that instead. this is still an imperfect mechanism because it doesn't handle a compiler which has both langFortran *and* langC very well - applying the superset of the two's hardeningUnsupportedFlags to either compiler's invocation. however this is nothing new - cc-wrapper already poorly handles a langFortran+langC compiler, applying two setup hooks that have contradictory options.
49bb1b7
to
dc2247a
Compare
Let's do this. Am currently re-testing on macos and linux. |
Cherry-picking #253186 (which could also do with review) to correct the tests, |
A release-notes entry for this: #273840 |
Fix for eval regression: #280537 |
Description of changes
New hardening flags on the horizon look like they're going to be a bit less "universal" and possibly have more tradeoffs (CET/CFI et al). So it will be useful to make custom selection of hardening flags as convenient as possible to work with. It would also be nice to make it easier for users to experiment with lesser-used hardening schemes in the hopes they'll get more exposure and bug squashing.
mkDerivation
has always been an awkward place fordefaultHardeningFlags
to be determined - these changes make it a lot easier to create a modified stdenv with a different set ofdefaultHardeningFlags
and as a bonus they allow us to inject the correctdefaultHardeningFlags
into toolchain wrapper scripts, reducing repetition.While most hardening flags are arguably more of a c-compiler thing, it works better to put them in
bintools-wrapper
becausecc-wrapper
can easily refer to bintools but not vice-versa.mkDerivation
can still easily refer to either when it is constructed.Note this is still different from a compiler's "supported" hardening flags (expressed via
cc.hardeningUnsupportedFlags
) which are used to filter out particular hardening flags at invocation time.This also adds
stdenvAdapters.withDefaultHardeningFlags
as a demonstration of the new abilities.Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)