diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index e643b2d059b5..8231907d7999 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -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; }; diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index d421167c859c..61c49f07abbb 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -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; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 3440261c3965..634f91a275d3 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -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" ]) diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix index 3f24118ea1cb..9d0249820d5d 100644 --- a/nixos/modules/security/grsecurity.nix +++ b/nixos/modules/security/grsecurity.nix @@ -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 - gradm. 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 - true 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 GRKERN_SYSCTL y. 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 - kernel.grsecurity.grsec_lock 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 GRKERN_CHROOT_CHMOD - y. If enabled, this denies processes inside a - chroot from setting the suid or sgid bits using - chmod or fchmod. - - 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 CAP_SYS_ADMIN. - - This protection is disabled by default because it breaks - nixos-rebuild. Whenever possible, it is - highly recommended to enable this protection. - ''; - }; - - denyUSB = mkOption { - type = types.bool; - default = false; - description = '' - If true, then set GRKERNSEC_DENYUSB y. - - This enables a sysctl with name - kernel.grsecurity.deny_new_usb. Setting - its value to 1 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 GRKERN_PROC_USER - y. 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 GRKERN_PROC_USERGROUP - y. This is similar to - restrictProc except it allows a special - group (specified by unrestrictProcGid) - to still access otherwise classified information in - /proc. - ''; - }; - - unrestrictProcGid = mkOption { - type = types.int; - default = config.ids.gids.grsecurity; - description = '' - If set, specifies a GID which is exempt from - /proc restrictions (set by - GRKERN_PROC_USERGROUP). By default, - this is set to the GID for grsecurity, - a predefined NixOS group, which the - root account is a member of. You may - conveniently add other users to this group if you need - access to /proc - ''; - }; - - disableRBAC = mkOption { - type = types.bool; - default = false; - description = '' - If true, then set GRKERN_NO_RBAC - y. This disables the - /dev/grsec device, which in turn - disables the RBAC system (and gradm). - ''; - }; - - 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 + (). Disable + this to allow configuration of grsecurity features while the system is + running. The lock can be manually engaged by activating the + grsec-lock 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; }; } diff --git a/nixos/tests/grsecurity.nix b/nixos/tests/grsecurity.nix index 14f1aa9ff885..aadbfd8371ff 100644 --- a/nixos/tests/grsecurity.nix +++ b/nixos/tests/grsecurity.nix @@ -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 \nint main(void) { puts(\"hello\"); return 0; }' >main.c"); + $machine->succeed("${pkgs.tinycc.bin}/bin/tcc -run main.c"); + }; + ''; }) - diff --git a/pkgs/applications/virtualization/qemu/default.nix b/pkgs/applications/virtualization/qemu/default.nix index ed59f5eb5108..4cdb2f7ec7d8 100644 --- a/pkgs/applications/virtualization/qemu/default.nix +++ b/pkgs/applications/virtualization/qemu/default.nix @@ -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. diff --git a/pkgs/build-support/grsecurity/default.nix b/pkgs/build-support/grsecurity/default.nix index 7777b6000628..8713f2d22c45 100644 --- a/pkgs/build-support/grsecurity/default.nix +++ b/pkgs/build-support/grsecurity/default.nix @@ -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 ""} + ''; +}) diff --git a/pkgs/build-support/grsecurity/flavors.nix b/pkgs/build-support/grsecurity/flavors.nix deleted file mode 100644 index 1281d60aa328..000000000000 --- a/pkgs/build-support/grsecurity/flavors.nix +++ /dev/null @@ -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; -} diff --git a/pkgs/os-specific/linux/kernel/common-config.nix b/pkgs/os-specific/linux/kernel/common-config.nix index 3ce65a3f6e18..624d380fe568 100644 --- a/pkgs/os-specific/linux/kernel/common-config.nix +++ b/pkgs/os-specific/linux/kernel/common-config.nix @@ -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 diff --git a/pkgs/os-specific/linux/kernel/grsecurity-nixos-config.nix b/pkgs/os-specific/linux/kernel/grsecurity-nixos-config.nix new file mode 100644 index 000000000000..894f2d8e3641 --- /dev/null +++ b/pkgs/os-specific/linux/kernel/grsecurity-nixos-config.nix @@ -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 +'' diff --git a/pkgs/os-specific/linux/kernel/grsecurity-path-4.5.patch b/pkgs/os-specific/linux/kernel/grsecurity-nixos-kmod.patch similarity index 100% rename from pkgs/os-specific/linux/kernel/grsecurity-path-4.5.patch rename to pkgs/os-specific/linux/kernel/grsecurity-nixos-kmod.patch diff --git a/pkgs/os-specific/linux/kernel/linux-grsecurity-4.5.nix b/pkgs/os-specific/linux/kernel/linux-grsecurity.nix similarity index 100% rename from pkgs/os-specific/linux/kernel/linux-grsecurity-4.5.nix rename to pkgs/os-specific/linux/kernel/linux-grsecurity.nix diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix index 877e51565ac2..0fa9708efe52 100644 --- a/pkgs/os-specific/linux/kernel/patches.nix +++ b/pkgs/os-specific/linux/kernel/patches.nix @@ -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 = diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 9fbc40ed4481..1402c4b7b9c8 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -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); diff --git a/pkgs/top-level/release.nix b/pkgs/top-level/release.nix index 5870f7abe78c..b596075a2ed0 100644 --- a/pkgs/top-level/release.nix +++ b/pkgs/top-level/release.nix @@ -332,11 +332,6 @@ let xfwm4 = linux; }; - linuxPackages_testing = { }; - linuxPackages_grsec_testing_desktop = { }; - linuxPackages_grsec_testing_server = { }; - linuxPackages_grsec_testing_server_xen = { }; - } )); in jobs