Merge pull request #16107 from joachifm/grsec-ng

Rework grsecurity support
This commit is contained in:
Joachim Fasting 2016-06-14 03:52:50 +02:00 committed by GitHub
commit 886c03ad2e
15 changed files with 315 additions and 571 deletions

View File

@ -468,7 +468,6 @@ in {
home = "/root";
shell = mkDefault cfg.defaultUserShell;
group = "root";
extraGroups = [ "grsecurity" ];
initialHashedPassword = mkDefault config.security.initialRootPassword;
};
nobody = {
@ -497,7 +496,6 @@ in {
nixbld.gid = ids.gids.nixbld;
utmp.gid = ids.gids.utmp;
adm.gid = ids.gids.adm;
grsecurity.gid = ids.gids.grsecurity;
input.gid = ids.gids.input;
};

View File

@ -147,7 +147,6 @@
foundationdb = 118;
newrelic = 119;
starbound = 120;
#grsecurity = 121; # unused
hydra = 122;
spiped = 123;
teamspeak = 124;
@ -396,7 +395,6 @@
foundationdb = 118;
newrelic = 119;
starbound = 120;
grsecurity = 121;
hydra = 122;
spiped = 123;
teamspeak = 124;

View File

@ -114,6 +114,26 @@ with lib;
(mkRenamedOptionModule [ "services" "iodined" "extraConfig" ] [ "services" "iodine" "server" "extraConfig" ])
(mkRemovedOptionModule [ "services" "iodined" "client" ])
# Grsecurity
(mkRemovedOptionModule [ "security" "grsecurity" "kernelPatch" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "mode" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "priority" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "system" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "virtualisationConfig" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "hardwareVirtualisation" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "virtualisationSoftware" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "sysctl" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "denyChrootChmod" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "denyChrootCaps" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "denyUSB" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "restrictProc" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "restrictProcWithGroup" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "unrestrictProcGid" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "disableRBAC" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "disableSimultConnect" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "verboseVersion" ])
(mkRemovedOptionModule [ "security" "grsecurity" "config" "kernelExtraConfig" ])
# Options that are obsolete and have no replacement.
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ])
(mkRemovedOptionModule [ "programs" "bash" "enable" ])

View File

@ -1,312 +1,122 @@
{ config, lib, pkgs, ... }:
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.security.grsecurity;
grsecLockPath = "/proc/sys/kernel/grsecurity/grsec_lock";
customGrsecPkg =
(import ../../../pkgs/build-support/grsecurity {
grsecOptions = cfg;
inherit pkgs lib;
}).grsecPackage;
# Ascertain whether ZFS is required for booting the system; grsecurity is
# currently incompatible with ZFS, rendering the system unbootable.
zfsNeededForBoot = filter
(fs: (fs.neededForBoot
|| elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ])
&& fs.fsType == "zfs")
(attrValues config.fileSystems) != [];
in
{
options = {
security.grsecurity = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable grsecurity support. This enables advanced exploit
hardening for the Linux kernel, and adds support for
administrative Role-Based Acess Control (RBAC) via
<literal>gradm</literal>. It also includes traditional
utilities for PaX.
'';
};
options.security.grsecurity = {
kernelPatch = mkOption {
type = types.attrs;
example = lib.literalExample "pkgs.kernelPatches.grsecurity_4_1";
description = ''
Grsecurity patch to use.
'';
};
enable = mkEnableOption "Grsecurity/PaX";
config = {
mode = mkOption {
type = types.enum [ "auto" "custom" ];
default = "auto";
description = ''
grsecurity configuration mode. This specifies whether
grsecurity is auto-configured or otherwise completely
manually configured.
'';
};
priority = mkOption {
type = types.enum [ "security" "performance" ];
default = "security";
description = ''
grsecurity configuration priority. This specifies whether
the kernel configuration should emphasize speed or
security.
'';
};
system = mkOption {
type = types.enum [ "desktop" "server" ];
default = "desktop";
description = ''
grsecurity system configuration.
'';
};
virtualisationConfig = mkOption {
type = types.nullOr (types.enum [ "host" "guest" ]);
default = null;
description = ''
grsecurity virtualisation configuration. This specifies
the virtualisation role of the machine - that is, whether
it will be a virtual machine guest, a virtual machine
host, or neither.
'';
};
hardwareVirtualisation = mkOption {
type = types.nullOr types.bool;
default = null;
example = true;
description = ''
grsecurity hardware virtualisation configuration. Set to
<literal>true</literal> if your machine supports hardware
accelerated virtualisation.
'';
};
virtualisationSoftware = mkOption {
type = types.nullOr (types.enum [ "kvm" "xen" "vmware" "virtualbox" ]);
default = null;
description = ''
Configure grsecurity for use with this virtualisation software.
'';
};
sysctl = mkOption {
type = types.bool;
default = false;
description = ''
If true, then set <literal>GRKERN_SYSCTL y</literal>. If
enabled then grsecurity can be controlled using sysctl
(and turned off). You are advised to *never* enable this,
but if you do, make sure to always set the sysctl
<literal>kernel.grsecurity.grsec_lock</literal> to
non-zero as soon as all sysctl options are set. *THIS IS
EXTREMELY IMPORTANT*!
'';
};
denyChrootChmod = mkOption {
type = types.bool;
default = false;
description = ''
If true, then set <literal>GRKERN_CHROOT_CHMOD
y</literal>. If enabled, this denies processes inside a
chroot from setting the suid or sgid bits using
<literal>chmod</literal> or <literal>fchmod</literal>.
By default this protection is disabled - it makes it
impossible to use Nix to build software on your system,
which is what most users want.
If you are using NixOps to deploy your software to a
remote machine, you're encouraged to enable this as you
won't need to compile code.
'';
};
denyChrootCaps = mkOption {
type = types.bool;
default = false;
description = ''
Whether to lower capabilities of all processes within a chroot,
preventing commands that require <literal>CAP_SYS_ADMIN</literal>.
This protection is disabled by default because it breaks
<literal>nixos-rebuild</literal>. Whenever possible, it is
highly recommended to enable this protection.
'';
};
denyUSB = mkOption {
type = types.bool;
default = false;
description = ''
If true, then set <literal>GRKERNSEC_DENYUSB y</literal>.
This enables a sysctl with name
<literal>kernel.grsecurity.deny_new_usb</literal>. Setting
its value to <literal>1</literal> will prevent any new USB
devices from being recognized by the OS. Any attempted
USB device insertion will be logged.
This option is intended to be used against custom USB
devices designed to exploit vulnerabilities in various USB
device drivers.
'';
};
restrictProc = mkOption {
type = types.bool;
default = false;
description = ''
If true, then set <literal>GRKERN_PROC_USER
y</literal>. This restricts non-root users to only viewing
their own processes and restricts network-related
information, kernel symbols, and module information.
'';
};
restrictProcWithGroup = mkOption {
type = types.bool;
default = true;
description = ''
If true, then set <literal>GRKERN_PROC_USERGROUP
y</literal>. This is similar to
<literal>restrictProc</literal> except it allows a special
group (specified by <literal>unrestrictProcGid</literal>)
to still access otherwise classified information in
<literal>/proc</literal>.
'';
};
unrestrictProcGid = mkOption {
type = types.int;
default = config.ids.gids.grsecurity;
description = ''
If set, specifies a GID which is exempt from
<literal>/proc</literal> restrictions (set by
<literal>GRKERN_PROC_USERGROUP</literal>). By default,
this is set to the GID for <literal>grsecurity</literal>,
a predefined NixOS group, which the
<literal>root</literal> account is a member of. You may
conveniently add other users to this group if you need
access to <literal>/proc</literal>
'';
};
disableRBAC = mkOption {
type = types.bool;
default = false;
description = ''
If true, then set <literal>GRKERN_NO_RBAC
y</literal>. This disables the
<literal>/dev/grsec</literal> device, which in turn
disables the RBAC system (and <literal>gradm</literal>).
'';
};
disableSimultConnect = mkOption {
type = types.bool;
default = false;
description = ''
Disable TCP simultaneous connect. The TCP simultaneous connect
feature allows two clients to connect without either of them
entering the listening state. This feature of the TCP specification
is claimed to enable an attacker to deny the target access to a given
server by guessing the source port the target would use to make the
connection.
This option is OFF by default because TCP simultaneous connect has
some legitimate uses. Enable this option if you know what this TCP
feature is for and know that you do not need it.
'';
};
verboseVersion = mkOption {
type = types.bool;
default = false;
description = "Use verbose version in kernel localversion.";
};
kernelExtraConfig = mkOption {
type = types.str;
default = "";
description = "Extra kernel configuration parameters.";
};
};
};
};
config = mkIf cfg.enable {
assertions =
[
{ assertion = (cfg.config.restrictProc -> !cfg.config.restrictProcWithGroup) ||
(cfg.config.restrictProcWithGroup -> !cfg.config.restrictProc);
message = "You cannot enable both restrictProc and restrictProcWithGroup";
}
{ assertion = config.boot.kernelPackages.kernel.features ? grsecurity
&& config.boot.kernelPackages.kernel.features.grsecurity;
message = "grsecurity enabled, but kernel doesn't have grsec support";
}
{ assertion = (cfg.config.mode == "auto" && (cfg.config.virtualisationConfig != null)) ->
cfg.config.hardwareVirtualisation != null;
message = "when using auto grsec mode with virtualisation, you must specify if your hardware has virtualisation extensions";
}
{ assertion = (cfg.config.mode == "auto" && (cfg.config.virtualisationConfig != null)) ->
cfg.config.virtualisationSoftware != null;
message = "grsecurity configured for virtualisation but no virtualisation software specified";
}
];
security.grsecurity.kernelPatch = lib.mkDefault pkgs.kernelPatches.grsecurity_latest;
systemd.services.grsec-lock = mkIf cfg.config.sysctl {
description = "grsecurity sysctl-lock Service";
wants = [ "systemd-sysctl.service" ];
after = [ "systemd-sysctl.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = "yes";
unitConfig.ConditionPathIsReadWrite = "/proc/sys/kernel/grsecurity/grsec_lock";
script = ''
locked=`cat /proc/sys/kernel/grsecurity/grsec_lock`
if [ "$locked" == "0" ]; then
echo 1 > /proc/sys/kernel/grsecurity/grsec_lock
echo grsecurity sysctl lock - enabled
else
echo grsecurity sysctl lock already enabled - doing nothing
fi
lockTunables = mkOption {
type = types.bool;
example = false;
default = true;
description = ''
Whether to automatically lock grsecurity tunables
(<option>boot.kernel.sysctl."kernel.grsecurity.*"</option>). Disable
this to allow configuration of grsecurity features while the system is
running. The lock can be manually engaged by activating the
<literal>grsec-lock</literal> service unit.
'';
};
# systemd.services.grsec-learn = {
# description = "grsecurity learning Service";
# wantedBy = [ "local-fs.target" ];
# serviceConfig = {
# Type = "oneshot";
# RemainAfterExit = "yes";
# ExecStart = "${pkgs.gradm}/sbin/gradm -VFL /etc/grsec/learning.logs";
# ExecStop = "${pkgs.gradm}/sbin/gradm -D";
# };
# };
};
system.activationScripts = lib.optionalAttrs (!cfg.config.disableRBAC) { grsec = ''
mkdir -p /etc/grsec
if [ ! -f /etc/grsec/learn_config ]; then
cp ${pkgs.gradm}/etc/grsec/learn_config /etc/grsec
fi
if [ ! -f /etc/grsec/policy ]; then
cp ${pkgs.gradm}/etc/grsec/policy /etc/grsec
fi
chmod -R 0600 /etc/grsec
''; };
config = mkIf cfg.enable {
# Allow the user to select a different package set, subject to the stated
# required kernel config
boot.kernelPackages = mkDefault pkgs.linuxPackages_grsec_nixos;
system.requiredKernelConfig = with config.lib.kernelConfig;
[ (isEnabled "GRKERNSEC")
(isEnabled "PAX")
(isYES "GRKERNSEC_SYSCTL")
(isYES "GRKERNSEC_SYSCTL_DISTRO")
];
# Crashing on an overflow in kernel land is user unfriendly and may prevent
# the system from booting, which is too severe for our use case.
boot.kernelParams = [ "pax_size_overflow_report_only" ];
# Install PaX related utillities into the system profile. Eventually, we
# also want to include gradm here.
environment.systemPackages = with pkgs; [ paxctl pax-utils ];
# Install rules for the grsec device node
services.udev.packages = [ pkgs.gradm ];
# This service unit is responsible for locking the Grsecurity tunables. The
# unit is always defined, but only activated on bootup if lockTunables is
# toggled. When lockTunables is toggled, failure to activate the unit will
# enter emergency mode. The intent is to make it difficult to silently
# enter multi-user mode without having locked the tunables. Some effort is
# made to ensure that starting the unit is an idempotent operation.
systemd.services.grsec-lock = {
description = "Lock grsecurity tunables";
wantedBy = optional cfg.lockTunables "multi-user.target";
wants = [ "local-fs.target" "systemd-sysctl.service" ];
after = [ "local-fs.target" "systemd-sysctl.service" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
script = ''
if ${pkgs.gnugrep}/bin/grep -Fq 0 ${grsecLockPath} ; then
echo -n 1 > ${grsecLockPath}
fi
'';
unitConfig = {
ConditionPathIsReadWrite = grsecLockPath;
DefaultDependencies = false;
} // optionalAttrs cfg.lockTunables {
OnFailure = "emergency.target";
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
};
# Configure system tunables
boot.kernel.sysctl = {
# Removed under grsecurity
"kernel.kptr_restrict" = mkForce null;
} // optionalAttrs config.nix.useSandbox {
# chroot(2) restrictions that conflict with sandboxed Nix builds
"kernel.grsecurity.chroot_caps" = mkForce 0;
"kernel.grsecurity.chroot_deny_chroot" = mkForce 0;
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
"kernel.grsecurity.chroot_deny_pivot" = mkForce 0;
} // optionalAttrs config.boot.enableContainers {
# chroot(2) restrictions that conflict with NixOS lightweight containers
"kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
"kernel.grsecurity.chroot_deny_mount" = mkForce 0;
"kernel.grsecurity.chroot_restrict_nice" = mkForce 0;
};
assertions = [
{ assertion = !zfsNeededForBoot;
message = "grsecurity is currently incompatible with ZFS";
}
];
# Enable AppArmor, gradm udev rules, and utilities
security.apparmor.enable = true;
boot.kernelPackages = customGrsecPkg;
services.udev.packages = lib.optional (!cfg.config.disableRBAC) pkgs.gradm;
environment.systemPackages = [ pkgs.paxctl pkgs.pax-utils ] ++ lib.optional (!cfg.config.disableRBAC) pkgs.gradm;
};
}

View File

@ -3,17 +3,39 @@
import ./make-test.nix ({ pkgs, ...} : {
name = "grsecurity";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ copumpkin ];
maintainers = [ copumpkin joachifm ];
};
machine = { config, pkgs, ... }:
{ boot.kernelPackages = pkgs.linuxPackages_grsec_testing_server; };
{ security.grsecurity.enable = true;
boot.kernel.sysctl."kernel.grsecurity.deter_bruteforce" = 0;
security.apparmor.enable = true;
};
testScript =
''
$machine->succeed("uname -a") =~ /grsec/;
# FIXME: this seems to hang the whole test. Unclear why, but let's fix it
# $machine->succeed("${pkgs.paxtest}/bin/paxtest blackhat");
'';
testScript = ''
subtest "grsec-lock", sub {
$machine->succeed("systemctl is-active grsec-lock");
$machine->succeed("grep -Fq 1 /proc/sys/kernel/grsecurity/grsec_lock");
$machine->fail("echo -n 0 >/proc/sys/kernel/grsecurity/grsec_lock");
};
subtest "paxtest", sub {
# TODO: running paxtest blackhat hangs the vm
$machine->succeed("${pkgs.paxtest}/lib/paxtest/anonmap") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/execbss") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/execdata") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/execheap") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/execstack") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/mprotanon") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/mprotbss") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/mprotdata") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/mprotheap") =~ /Killed/ or die;
$machine->succeed("${pkgs.paxtest}/lib/paxtest/mprotstack") =~ /Killed/ or die;
};
subtest "tcc", sub {
$machine->execute("echo -e '#include <stdio.h>\nint main(void) { puts(\"hello\"); return 0; }' >main.c");
$machine->succeed("${pkgs.tinycc.bin}/bin/tcc -run main.c");
};
'';
})

View File

@ -60,6 +60,13 @@ stdenv.mkDerivation rec {
++ optional stdenv.isDarwin "--enable-cocoa"
++ optional stdenv.isLinux "--enable-linux-aio";
postFixup =
''
for exe in $out/bin/qemu-system-* ; do
paxmark m $exe
done
'';
postInstall =
''
# Add a qemu-kvm wrapper for compatibility/convenience.

View File

@ -1,158 +1,33 @@
{ grsecOptions, lib, pkgs }:
{ stdenv
, overrideDerivation
with lib;
# required for gcc plugins
, gmp, libmpc, mpfr
let
cfg = {
kernelPatch = grsecOptions.kernelPatch;
config = {
mode = "auto";
sysctl = false;
denyChrootCaps = false;
denyChrootChmod = false;
denyUSB = false;
restrictProc = false;
restrictProcWithGroup = true;
unrestrictProcGid = 121; # Ugh, an awful hack. See grsecurity NixOS gid
disableRBAC = false;
disableSimultConnect = false;
redistKernel = true;
verboseVersion = false;
kernelExtraConfig = "";
} // grsecOptions.config;
};
# the base kernel
, kernel
vals = rec {
, grsecPatch
, kernelPatches ? []
mkKernel = patch:
{
inherit patch;
inherit (patch) kernel patches grversion revision;
};
, localver ? "-grsec"
, modDirVersion ? "${kernel.version}${localver}"
, extraConfig ? ""
, ...
} @ args:
grKernel = mkKernel cfg.kernelPatch;
assert (kernel.version == grsecPatch.kver);
## -- grsecurity configuration ---------------------------------------------
grsecPrioCfg =
if cfg.config.priority == "security" then
"GRKERNSEC_CONFIG_PRIORITY_SECURITY y"
else
"GRKERNSEC_CONFIG_PRIORITY_PERF y";
grsecSystemCfg =
if cfg.config.system == "desktop" then
"GRKERNSEC_CONFIG_DESKTOP y"
else
"GRKERNSEC_CONFIG_SERVER y";
grsecVirtCfg =
if cfg.config.virtualisationConfig == null then
"GRKERNSEC_CONFIG_VIRT_NONE y"
else if cfg.config.virtualisationConfig == "host" then
"GRKERNSEC_CONFIG_VIRT_HOST y"
else
"GRKERNSEC_CONFIG_VIRT_GUEST y";
grsecHwvirtCfg = if cfg.config.virtualisationConfig == null then "" else
if cfg.config.hardwareVirtualisation == true then
"GRKERNSEC_CONFIG_VIRT_EPT y"
else
"GRKERNSEC_CONFIG_VIRT_SOFT y";
grsecVirtswCfg =
let virtCfg = opt: "GRKERNSEC_CONFIG_VIRT_"+opt+" y";
in
if cfg.config.virtualisationConfig == null then ""
else if cfg.config.virtualisationSoftware == "xen" then virtCfg "XEN"
else if cfg.config.virtualisationSoftware == "kvm" then virtCfg "KVM"
else if cfg.config.virtualisationSoftware == "vmware" then virtCfg "VMWARE"
else virtCfg "VIRTUALBOX";
grsecMainConfig = if cfg.config.mode == "custom" then "" else ''
GRKERNSEC_CONFIG_AUTO y
${grsecPrioCfg}
${grsecSystemCfg}
${grsecVirtCfg}
${grsecHwvirtCfg}
${grsecVirtswCfg}
'';
grsecConfig =
let boolToKernOpt = b: if b then "y" else "n";
# Disable RANDSTRUCT under virtualbox, as it has some kind of
# breakage with the vbox guest drivers
#randstruct = optionalString config.virtualisation.virtualbox.guest.enable
# "GRKERNSEC_RANDSTRUCT n";
# Disable restricting links under the testing kernel, as something
# has changed causing it to fail miserably during boot.
#restrictLinks = optionalString cfg.testing
# "GRKERNSEC_LINK n";
in ''
GRKERNSEC y
${grsecMainConfig}
# Disable features rendered useless by redistributing the kernel
${optionalString cfg.config.redistKernel ''
GRKERNSEC_RANDSTRUCT n
GRKERNSEC_HIDESYM n
''}
# The paxmarks mechanism relies on ELF header markings, but the default
# grsecurity configuration only enables xattr markings
PAX_PT_PAX_FLAGS y
${if cfg.config.restrictProc then
"GRKERNSEC_PROC_USER y"
else
optionalString cfg.config.restrictProcWithGroup ''
GRKERNSEC_PROC_USERGROUP y
GRKERNSEC_PROC_GID ${toString cfg.config.unrestrictProcGid}
''
}
GRKERNSEC_SYSCTL ${boolToKernOpt cfg.config.sysctl}
GRKERNSEC_CHROOT_CAPS ${boolToKernOpt cfg.config.denyChrootCaps}
GRKERNSEC_CHROOT_CHMOD ${boolToKernOpt cfg.config.denyChrootChmod}
GRKERNSEC_DENYUSB ${boolToKernOpt cfg.config.denyUSB}
GRKERNSEC_NO_RBAC ${boolToKernOpt cfg.config.disableRBAC}
GRKERNSEC_NO_SIMULT_CONNECT ${boolToKernOpt cfg.config.disableSimultConnect}
${cfg.config.kernelExtraConfig}
'';
## -- grsecurity kernel packages -------------------------------------------
localver = grkern:
"-grsec" + optionalString cfg.config.verboseVersion
"-${grkern.grversion}-${grkern.revision}";
grsecurityOverrider = args: grkern: {
# additional build inputs for gcc plugins, required by some PaX/grsec features
nativeBuildInputs = args.nativeBuildInputs ++ (with pkgs; [ gmp libmpc mpfr ]);
preConfigure = (args.preConfigure or "") + ''
echo ${localver grkern} > localversion-grsec
'';
};
mkGrsecKern = grkern:
lowPrio (overrideDerivation (grkern.kernel.override (args: {
kernelPatches = args.kernelPatches ++ [ grkern.patch ] ++ grkern.patches;
argsOverride = {
modDirVersion = "${grkern.kernel.modDirVersion}${localver grkern}";
};
extraConfig = grsecConfig;
features.grsecurity = true;
ignoreConfigErrors = true; # Too lazy to model the config options that work with grsecurity and don't for now
})) (args: grsecurityOverrider args grkern));
mkGrsecPkg = grkern: pkgs.linuxPackagesFor grkern (mkGrsecPkg grkern);
## -- Kernel packages ------------------------------------------------------
grsecKernel = mkGrsecKern grKernel;
grsecPackage = mkGrsecPkg grsecKernel;
};
in vals
overrideDerivation (kernel.override {
inherit modDirVersion;
kernelPatches = [ { inherit (grsecPatch) name patch; } ] ++ kernelPatches ++ (kernel.kernelPatches or []);
features = (kernel.features or {}) // { grsecurity = true; };
inherit extraConfig;
ignoreConfigErrors = true;
}) (attrs: {
nativeBuildInputs = [ gmp libmpc mpfr ] ++ (attrs.nativeBuildInputs or []);
preConfigure = ''
echo ${localver} >localversion-grsec
${attrs.preConfigure or ""}
'';
})

View File

@ -1,17 +0,0 @@
let
mkOpts = prio: sys: virt: swvirt: hwvirt:
{ config.priority = prio;
config.system = sys;
config.virtualisationConfig = virt;
config.hardwareVirtualisation = hwvirt;
config.virtualisationSoftware = swvirt;
};
in
{
desktop =
mkOpts "performance" "desktop" "host" "kvm" true;
server =
mkOpts "security" "server" "host" "kvm" true;
server_xen =
mkOpts "security" "server" "guest" "xen" true;
}

View File

@ -261,9 +261,7 @@ with stdenv.lib;
# Security related features.
STRICT_DEVMEM y # Filter access to /dev/mem
SECURITY_SELINUX_BOOTPARAM_VALUE 0 # Disable SELinux by default
${optionalString (!(features.grsecurity or false)) ''
DEVKMEM n # Disable /dev/kmem
''}
DEVKMEM n # Disable /dev/kmem
${if versionOlder version "3.14" then ''
CC_STACKPROTECTOR? y # Detect buffer overflows on the stack
'' else ''
@ -422,13 +420,11 @@ with stdenv.lib;
# Virtualisation.
PARAVIRT? y
${optionalString (!(features.grsecurity or false))
(if versionAtLeast version "3.10" then ''
HYPERVISOR_GUEST y
'' else ''
PARAVIRT_GUEST? y
'')
}
${if versionAtLeast version "3.10" then ''
HYPERVISOR_GUEST y
'' else ''
PARAVIRT_GUEST? y
''}
KVM_APIC_ARCHITECTURE y
KVM_ASYNC_PF y
${optionalString (versionOlder version "3.7") ''
@ -443,9 +439,7 @@ with stdenv.lib;
${optionalString (versionAtLeast version "4.0") ''
KVM_GENERIC_DIRTYLOG_READ_PROTECT y
''}
${optionalString (!features.grsecurity or true) ''
KVM_GUEST y
''}
KVM_GUEST y
KVM_MMIO y
${optionalString (versionAtLeast version "3.13") ''
KVM_VFIO y

View File

@ -0,0 +1,43 @@
{ stdenv }:
with stdenv.lib;
''
GRKERNSEC y
PAX y
GRKERNSEC_CONFIG_AUTO y
GRKERNSEC_CONFIG_DESKTOP y
GRKERNSEC_CONFIG_VIRT_HOST y
GRKERNSEC_CONFIG_VIRT_EPT y
GRKERNSEC_CONFIG_VIRT_KVM y
GRKERNSEC_CONFIG_PRIORITY_SECURITY y
PAX_PT_PAX_FLAGS y
PAX_XATTR_PAX_FLAGS n
PAX_EI_PAX n
GRKERNSEC_PROC_GID 0
PAX_LATENT_ENTROPY n
PAX_SIZE_OVERFLOW n
GRKERNSEC_HIDESYM n
GRKERNSEC_RANDSTRUCT n
GRKERNSEC_PROC n
GRKERNSEC_SYSFS_RESTRICT n
GRKERNSEC_KMEM n
GRKERNSEC_MODHARDEN n
GRKERNSEC_NO_SIMULT_CONNECT n
PAX_KERNEXEC_PLUGIN_METHOD_BTS y
GRKERNSEC_ACL_HIDEKERN y
GRKERNSEC_IO y
GRKERNSEC_AUDIT_PTRACE y
GRKERNSEC_FORKFAIL y
GRKERNSEC_SYSCTL y
GRKERNSEC_SYSCTL_DISTRO y
GRKERNSEC_SYSCTL_ON y
''

View File

@ -18,20 +18,20 @@ let
};
};
grsecPatch = { grversion ? "3.1", kernel, patches, kversion, revision, branch ? "test", sha256 }:
assert kversion == kernel.version;
{ name = "grsecurity-${grversion}-${kversion}";
inherit grversion kernel patches kversion revision;
grsecPatch = { grbranch ? "test", grver ? "3.1", kver, grrev, sha256 }: rec {
name = "grsecurity-${grver}-${kver}-${grrev}";
# Pass these along to allow the caller to determine compatibility
inherit grver kver grrev;
patch = fetchurl {
# When updating versions/hashes, ALWAYS use the official version; we use
# this mirror only because upstream removes sources files immediately upon
# releasing a new version ...
patch = fetchurl {
url = "https://raw.githubusercontent.com/slashbeast/grsecurity-scrape/master/test/grsecurity-${grversion}-${kversion}-${revision}.patch";
inherit sha256;
};
features.grsecurity = true;
url = "https://raw.githubusercontent.com/slashbeast/grsecurity-scrape/master/${grbranch}/${name}.patch";
inherit sha256;
};
};
in
rec {
@ -92,19 +92,18 @@ rec {
grsecurity_4_4 = throw "grsecurity stable is no longer supported";
grsecurity_4_5 = grsecPatch
{ kernel = pkgs.grsecurity_base_linux_4_5;
patches = [ grsecurity_fix_path_4_5 ];
kversion = "4.5.7";
revision = "201606080852";
sha256 = "1vgc314nh6bd7zw9r927lnbjq29z32g0s02jgvf635y9zz550nsh";
grsecurity_testing = grsecPatch
{ kver = "4.5.7";
grrev = "201606080852";
sha256 = "1vgc314nh6bd7zw9r927lnbjq29z32g0s02jgvf635y9zz550nsh";
};
grsecurity_latest = grsecurity_4_5;
grsecurity_fix_path_4_5 =
{ name = "grsecurity-fix-path-4.5";
patch = ./grsecurity-path-4.5.patch;
# This patch relaxes grsec constraints on the location of usermode helpers,
# e.g., modprobe, to allow calling into the Nix store.
grsecurity_nixos_kmod =
{
name = "grsecurity-nixos-kmod";
patch = ./grsecurity-nixos-kmod.patch;
};
crc_regression =

View File

@ -10822,32 +10822,6 @@ in
linux_chromiumos_latest = self.linux_chromiumos_3_18;
# grsecurity configuration
grsecurity_base_linux_4_5 = callPackage ../os-specific/linux/kernel/linux-grsecurity-4.5.nix {
inherit (linux_4_5) kernelPatches;
};
grFlavors = import ../build-support/grsecurity/flavors.nix;
mkGrsecurity = patch: opts:
(callPackage ../build-support/grsecurity {
grsecOptions = { kernelPatch = patch; } // opts;
});
grKernel = patch: opts: (self.mkGrsecurity patch opts).grsecKernel;
grPackage = patch: opts: recurseIntoAttrs (self.mkGrsecurity patch opts).grsecPackage;
# grsecurity kernels (see also linuxPackages_grsec_*)
linux_grsec_desktop_4_5 = self.grKernel kernelPatches.grsecurity_4_5 self.grFlavors.desktop;
linux_grsec_server_4_5 = self.grKernel kernelPatches.grsecurity_4_5 self.grFlavors.server;
linux_grsec_server_xen_4_5 = self.grKernel kernelPatches.grsecurity_4_5 self.grFlavors.server_xen;
linux_grsec_desktop_latest = self.grKernel kernelPatches.grsecurity_latest self.grFlavors.desktop;
linux_grsec_server_latest = self.grKernel kernelPatches.grsecurity_latest self.grFlavors.server;
linux_grsec_server_xen_latest = self.grKernel kernelPatches.grsecurity_latest self.grFlavors.server_xen;
/* Linux kernel modules are inherently tied to a specific kernel. So
rather than provide specific instances of those packages for a
specific kernel, we have a function that builds those packages
@ -10997,52 +10971,78 @@ in
# Build a kernel for Xen dom0
linuxPackages_latest_xen_dom0 = recurseIntoAttrs (self.linuxPackagesFor (self.linux_latest.override { features.xen_dom0=true; }) linuxPackages_latest);
# grsecurity packages
# Grsecurity packages
linuxPackages_grsec_desktop_4_5 = self.grPackage kernelPatches.grsecurity_4_5 self.grFlavors.desktop;
linuxPackages_grsec_server_4_5 = self.grPackage kernelPatches.grsecurity_4_5 self.grFlavors.server;
linuxPackages_grsec_server_xen_4_5 = self.grPackage kernelPatches.grsecurity_4_5 self.grFlavors.server_xen;
linux_grsec_nixos = callPackage ../build-support/grsecurity {
inherit (lib) overrideDerivation;
kernel = callPackage ../os-specific/linux/kernel/linux-grsecurity.nix {
inherit (self.linux_4_5) kernelPatches;
};
grsecPatch = self.kernelPatches.grsecurity_testing;
kernelPatches = [ self.kernelPatches.grsecurity_nixos_kmod ];
extraConfig = callPackage ../os-specific/linux/kernel/grsecurity-nixos-config.nix { };
};
linuxPackages_grsec_desktop_latest = self.grPackage kernelPatches.grsecurity_latest self.grFlavors.desktop;
linuxPackages_grsec_server_latest = self.grPackage kernelPatches.grsecurity_latest self.grFlavors.server;
linuxPackages_grsec_server_xen_latest = self.grPackage kernelPatches.grsecurity_latest self.grFlavors.server_xen;
linuxPackages_grsec_nixos =
let self = linuxPackagesFor linux_grsec_nixos self;
in recurseIntoAttrs self;
# An unsupported grsec xen guest kernel
linux_grsec_server_xen = linux_grsec_nixos.override {
extraConfig = ''
GRKERNSEC y
PAX y
GRKERNSEC_CONFIG_AUTO y
GRKERNSEC_CONFIG_PRIORITY_SECURITY y
GRKERNSEC_CONFIG_SERVER y
GRKERNSEC_CONFIG_VIRT_GUEST y
GRKERNSEC_CONFIG_VIRT_XEN y
'';
};
# grsecurity: legacy
grsecurity_base_linux_3_14 = throw "grsecurity stable is no longer supported";
grsecurity_base_linux_4_4 = throw "grsecurity stable is no longer supported";
linuxPackages_grsec_desktop_3_14 = throw "linuxPackages_grsec_desktop has been removed";
linuxPackages_grsec_desktop_4_4 = throw "linuxPackages_grsec_desktop has been removed";
linuxPackages_grsec_desktop_4_5 = throw "linuxPackages_grsec_desktop has been removed";
linuxPackages_grsec_desktop_latest = throw "linuxPackages_grsec_desktop has been removed";
linuxPackages_grsec_server_3_14 = throw "linuxPackages_grsec_server has been removed";
linuxPackages_grsec_server_4_4 = throw "linuxPackages_grsec_server has been removed";
linuxPackages_grsec_server_4_5 = throw "linuxPackages_grsec_server has been removed";
linuxPackages_grsec_server_latest = throw "linuxPackages_grsec_server has been removed";
linuxPackages_grsec_server_xen_3_14 = throw "linuxPackages_grsec_server_xen has been removed";
linuxPackages_grsec_server_xen_4_4 = throw "linuxPackages_grsec_server_xen has been removed";
linuxPackages_grsec_server_xen_4_5 = throw "linuxPackages_grsec_server_xen has been removed";
linuxPackages_grsec_server_xen_latest = throw "linuxPackages_grsec_server_xen has been removed";
linux_grsec_desktop_3_14 = throw "grsecurity stable is no longer supported";
linux_grsec_server_3_14 = throw "grsecurity stable is no longer supported";
linux_grsec_server_xen_3_14 = throw "grsecurity stable is no longer supported";
linux_grsec_desktop_4_4 = throw "grsecurity stable is no longer supported";
linux_grsec_server_4_4 = throw "grsecurity stable is no longer supported";
linux_grsec_server_xen_4_4 = throw "grsecurity stable is no longer supported";
linux_grsec_desktop_4_5 = throw "linux_grsec_desktop has been removed";
linux_grsec_desktop_latest = throw "linux_grsec_desktop has been removed";
linux_grsec_testing_desktop = self.linux_grsec_desktop_latest;
linux_grsec_testing_server = self.linux_grsec_server_latest;
linux_grsec_testing_server_xen = self.linux_grsec_server_xen_latest;
linux_grsec_server_3_14 = throw "grsecurity stable is no longer supported";
linux_grsec_server_4_4 = throw "grsecurity stable is no longer supported";
linux_grsec_server_4_5 = throw "linux_grsec_server has been removed";
linux_grsec_server_latest = throw "linux_grsec_server_latest has been removed";
linux_grsec_server_xen_3_14 = throw "grsecurity stable is no longer supported";
linux_grsec_server_xen_4_4 = throw "grsecurity stable is no longer supported";
linux_grsec_server_xen_4_5 = throw "linux_grsec_server_xen has been removed";
linux_grsec_server_xen_latest = throw "linux_grsec_server_xen has been removed";
linux_grsec_stable_desktop = self.linux_grsec_desktop_3_14;
linux_grsec_stable_server = self.linux_grsec_server_3_14;
linux_grsec_stable_server_xen = self.linux_grsec_server_xen_3_14;
linuxPackages_grsec_desktop_3_14 = self.grPackage kernelPatches.grsecurity_3_14 self.grFlavors.desktop;
linuxPackages_grsec_server_3_14 = self.grPackage kernelPatches.grsecurity_3_14 self.grFlavors.server;
linuxPackages_grsec_server_xen_3_14 = self.grPackage kernelPatches.grsecurity_3_14 self.grFlavors.server_xen;
linux_grsec_testing_desktop = self.linux_grsec_desktop_latest;
linux_grsec_testing_server = self.linux_grsec_server_latest;
linux_grsec_testing_server_xen = self.linux_grsec_server_xen_latest;
linuxPackages_grsec_desktop_4_4 = self.grPackage kernelPatches.grsecurity_4_4 self.grFlavors.desktop;
linuxPackages_grsec_server_4_4 = self.grPackage kernelPatches.grsecurity_4_4 self.grFlavors.server;
linuxPackages_grsec_server_xen_4_4 = self.grPackage kernelPatches.grsecurity_4_4 self.grFlavors.server_xen;
linuxPackages_grsec_testing_desktop = self.linuxPackages_grsec_desktop_latest;
linuxPackages_grsec_testing_server = self.linuxPackages_grsec_server_latest;
linuxPackages_grsec_testing_server_xen = self.linuxPackages_grsec_server_xen_latest;
linuxPackages_grsec_stable_desktop = self.linuxPackages_grsec_desktop_3_14;
linuxPackages_grsec_stable_server = self.linuxPackages_grsec_server_3_14;
linuxPackages_grsec_stable_server_xen = self.linuxPackages_grsec_server_xen_3_14;
# ChromiumOS kernels
linuxPackages_chromiumos_3_14 = recurseIntoAttrs (self.linuxPackagesFor self.linux_chromiumos_3_14 linuxPackages_chromiumos_3_14);

View File

@ -332,11 +332,6 @@ let
xfwm4 = linux;
};
linuxPackages_testing = { };
linuxPackages_grsec_testing_desktop = { };
linuxPackages_grsec_testing_server = { };
linuxPackages_grsec_testing_server_xen = { };
} ));
in jobs