This patch replaces the old grsecurity kernels with a single NixOS
specific grsecurity kernel. This kernel is intended as a general
purpose kernel, tuned for casual desktop use.
Providing only a single kernel may seem like a regression compared to
offering a multitude of flavors. It is impossible, however, to
effectively test and support that many options. This is amplified by
the reality that very few seem to actually use grsecurity on NixOS,
meaning that bugs go unnoticed for long periods of time, simply because
those code paths end up never being exercised. More generally, it is
hopeless to anticipate imagined needs. It is better to start from a
solid foundation and possibly add more flavours on demand.
While the generic kernel is intended to cover a wide range of use cases,
it cannot cover everything. For some, the configuration will be either
too restrictive or too lenient. In those cases, the recommended
solution is to build a custom kernel --- this is *strongly* recommended
for security sensitive deployments.
Building a custom grsec kernel should be as simple as
```nix
linux_grsec_nixos.override {
extraConfig = ''
GRKERNSEC y
PAX y
# and so on ...
'';
}
```
The generic kernel should be usable both as a KVM guest and host. When
running as a host, the kernel assumes hardware virtualisation support.
Virtualisation systems other than KVM are *unsupported*: users of
non-KVM systems are better served by compiling a custom kernel.
Unlike previous Grsecurity kernels, this configuration disables `/proc`
restrictions in favor of `security.hideProcessInformation`.
Known incompatibilities:
- ZFS: can't load spl and zfs kernel modules; claims incompatibility
with KERNEXEC method `or` and RAP; changing to `bts` does not fix the
problem, which implies we'd have to disable RAP as well for ZFS to
work
- `kexec()`: likely incompatible with KERNEXEC (unverified)
- Xen: likely incompatible with KERNEXEC and UDEREF (unverified)
- Virtualbox: likely incompatible with UDEREF (unverified)
Per my own testing, the NixOS grsecurity kernel works both as a
KVM-based virtualisation host and guest; there appears to be no good
reason to making these conditional on `features.grsecurity`.
More generally, it's unclear what `features.grsecurity` *means*. If
someone configures a grsecurity kernel in such a fashion that it breaks
KVM support, they should know to disable KVM themselves.
This was presumably set for grsecurity compatibility, but now appears
redundant. Grsecurity does not expect nor require /dev/kmem to be
present and so it makes little sense to continue making its inclusion in
the standard kernel dependent on grsecurity.
More generally, given the large number of possible grsecurity
configurations, it is unclear what `features.grsecurity` even
*means* and its use should be discouraged.
Also revert to using the grsecurity-scrape mirror; relying on upstream
just isn't viable. Lately, updates have been so frequent that a new
version is released before Hydra even gets around to building the
previous one.
It takes some extra 13MB (and in dev, not out), but allows perf to show kernel
symbols when profiling. I think it is worth it.
In my NixOS, I refer to it in the system derivation, for easy telling to perf
through /run/booted-system/vmlinux:
system.extraSystemBuilderCmds = ''
ln -s ${config.boot.kernelPackages.kernel.dev}/vmlinux $out/vmlinux
'';
From now on, only the testing branch of grsecurity will be supported.
Additionally, use only patches from upstream.
It's impossible to provide meaningful support for grsecurity stable.
First, because building and testing \(m \times n \times z) [1], packages
is infeasible. Second, because stable patches are only available from
upstream for-pay, making us reliant on third-parties for patches. In
addition to creating yet more work for the maintainers, using stable
patches provided by a third-party goes against the wishes of upstream.
nixpkgs provides the tools necessary to build grsecurity kernels for any
version the user chooses, however, provided they pay for, or otherwise
acquire, the patch themselves.
Eventually, we'll want to remove the now obsolete top-level attributes,
but leave them in for now to smoothe migration (they have been removed
from top-level/release.nix, though, because it makes no sense to have
them there).
[1]: where \(m\) is the number of grsecurity flavors, \(n\) is the
number of kernel versions, and z is the size of the `linuxPackages` set