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
linux: make sure all config options have the same value #90065
Conversation
without a merge feature, it would be too easy to break kernel configs and one of my goal was to make kernel configs more composable. I believe it's of higher priority to ease enabling stuff vs disabling stuff hence the default merge favors enabling feature. I would say it is mostly a matter of documentation as it should be possible to switch the behavior quite easily (change the order to have "n" first in:
whole common-config.nix should be a mkDefault IMO. If you are interested, I had a roadmap here #69014 |
Do you have a use case where a feature is explicitly disabled somewhere, enabled somewhere else and yet you want the result to be that the feature gets enabled? This is exactly what we don't want to happen in the use case I mentioned before (when someone wants to disable a feature for security reasons). IMO it's better for the build to break if there are conflicting definitions inside IMO the current merge strategy of silently choosing one value when there are conflicting definitions is extremely unintuitive, has led to undesired configurations for quite a long time (in hardened kernels and also for user configs, although I understand the latter will be fixed with mkDefault) and will very likely lead to the same problem in the future. I agree that using |
I marked this as stale due to inactivity. → More info |
I would like to keep the merging functions to provide different strategies. I will write some doc about kernel configuration now that it looks easier to do so. I can try to use mkDefault as discussed instead. |
INET_RAW_DIAG = whenAtLeast "4.14" module; | ||
INET_DIAG_DESTROY = whenAtLeast "4.9" yes; | ||
# Use a lower priority to allow these options to be overridden in hardened/config.nix | ||
INET_DIAG = mkOverride 1100 module; |
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.
I'd prefer mkDefault
here.
@teto if multiple places with the same priority disagree on what the option should be set to, I do think it should complain and require a human to decide what should be used. |
Alternatively, common-config could have
rather than |
@@ -78,6 +78,13 @@ assert (versionAtLeast version "4.9"); | |||
PROC_KCORE = no; # Exposes kernel text image layout | |||
INET_DIAG = no; # Has been used for heap based attacks in the past | |||
|
|||
# INET_DIAG=n causes the following options to not exist anymore, but since they are defined in common-config.nix, | |||
# make them optional | |||
INET_DIAG_DESTROY = option no; |
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.
Would INET_DIAG_DESTROY = null
unset this option?
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.
error: The option value `settings.INET_DIAG_DESTROY' in `structuredExtraConfig' is not of type `submodule'.
Maybe this could be made to work by adjusting the type a bit, but I don't think there's much point investing any effort into that when we can leave it as option no
.
I would suggest adding |
Additionally, I would add a |
I'd prefer using |
I can agree with that reasoning. Sounds good to me. |
@wizeman are you willing to do this? If not I'll pick it up sometime soon probably. |
Sounds good, ping me when you want another review :) |
@lheckemann Please, feel free to pick up. I don't think I will be able to finish this anytime soon. |
Currently, kernel config options whose value is "yes" always override options whose value is "no". This is not always desired. Generally speaking, if someone defines an option to have the value "no", presumably they are disabling the option for a reason, so it's not always OK to silently enable it due to another, probably unrelated reason. For example, a user may want to reduce the kernel attack surface and therefore may want to disable features that are being enabled in common-config.nix. In fact, common-config.nix was already silently enabling options that were intended to be disabled in hardened/config.nix for security reasons, such as INET_DIAG. By eliminating the custom merge function, these config options will now use the default module option merge functions which make sure that all options with the highest priority have the same value. A user that wishes to override an option defined in common-config.nix can currently use mkForce or mkOverride to do so, e.g.: BINFMT_MISC = mkForce (option no); That said, this is not going to be necessary in the future, because the plan is for kernel config options defined in nixpkgs to use a lower priority by default, like it currently happens for other module options.
The parent commit forbids conflicting kernel config options. Fix the hardened kernels by allowing options in common-config.nix to be overridden by conflicting ones in hardened/config.nix. I'm explicitly avoiding using a higher priority (e.g. using mkForce) in hardened/config.nix so that the user can easily override the options in that file.
d73ae97
to
d81067f
Compare
Done, @NeQuissimus what do you think? |
@ofborg test kernel-latest kernel-lts latestKernel.login kernel-latest-ath-user-regd latestKernel.hardened |
error: The option `settings.NIXOS_TEST_BOOLEAN.tristate' has conflicting definition values: - In `structuredExtraConfig': "n" - In `structuredExtraConfig': "y" since NixOS#90065 yes does not silently win over no
Motivation for this change
Currently, kernel config options whose value is
yes
always overrideoptions whose value is
no
.This is not always desired.
Generally speaking, if someone defines an option to have the value
no
, presumably they are disabling the option for a reason, so it'snot always OK to silently enable it due to another, probably unrelated
reason.
For example, a user may want to reduce the kernel attack surface and
therefore may want to disable features that are being enabled in
common-config.nix
.In fact,
common-config.nix
was already silently enabling options thatwere intended to be disabled in
hardened/config.nix
for securityreasons, such as
INET_DIAG
.By eliminating the custom merge function, these config options will
now use the default module option merge functions which make sure
that all options with the highest priority have the same value.
A user that wishes to override an option defined in
common-config.nix
can currently use
mkForce
ormkOverride
to do so, e.g.:That said, this is not going to be necessary in the future, because
the plan is for kernel config options defined in nixpkgs to use a
lower priority by default, like it currently happens for other module
options.
I've also added a commit that (along with #90057, which fixes other unrelated problems) fixes the hardened kernel builds due to said conflicting definitions.
Note: this came about due to #88946 (comment) and the following comments.
I know @teto expressed his opinion that the current merge strategy is fine as long as it's documented, but I disagree for the above reasons, and would like to discuss this issue on its own.
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)I've tested building the following kernels:
cc @teto @vcunat