Skip to content
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_*_hardened: use linux-hardened patch set #84522

Merged
merged 30 commits into from
Apr 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
10dd3f3
graphene-hardened-malloc: enable on aarch64-linux
emilazy Apr 8, 2020
3d01e80
linux: explicitly enable SYSVIPC
emilazy Apr 5, 2020
0d4f35e
linux_*_hardened: use linux-hardened patch set
emilazy Apr 4, 2020
7d5352d
linux_*_hardened: don't set X86_X32
emilazy Apr 5, 2020
3d4c8ae
linux_*_hardened: don't set VMAP_STACK
emilazy Apr 5, 2020
8efe83c
linux_*_hardened: don't set DEFAULT_MMAP_MIN_ADDR
emilazy Apr 4, 2020
8c68055
linux_*_hardened: don't set MODIFY_LDT_SYSCALL
emilazy Apr 4, 2020
130f681
linux_*_hardened: don't set RANDOMIZE_{BASE,MEMORY}
emilazy Apr 4, 2020
db6b327
linux_*_hardened: don't set LEGACY_VSYSCALL_NONE
emilazy Apr 4, 2020
33b94e5
linux_*_hardened: don't set BUG_ON_DATA_CORRUPTION
emilazy Apr 4, 2020
303bb60
linux_*_hardened: don't set DEBUG_WX
emilazy Apr 4, 2020
0611462
linux_*_hardened: don't set {,IO_}STRICT_DEVMEM
emilazy Apr 4, 2020
3eeb524
linux_*_hardened: don't set DEBUG_LIST
emilazy Apr 4, 2020
4fb796e
linux_*_hardened: don't set HARDENED_USERCOPY_FALLBACK
emilazy Apr 4, 2020
0d5f169
linux_*_hardened: don't set SLAB_FREELIST_{RANDOM,HARDENED}
emilazy Apr 4, 2020
ed89b5b
linux_*_hardened: don't set PANIC_ON_OOPS
emilazy Apr 4, 2020
7fdfe53
linux_*_hardened: don't set FORTIFY_SOURCE
emilazy Apr 4, 2020
3b32cd2
nixos/hardened: don't set slab_nomerge
emilazy Apr 5, 2020
cf1bce6
nixos/hardened: don't set vsyscall=none
emilazy Apr 5, 2020
9da578a
nixos/hardened: don't set kernel.dmesg_restrict
emilazy Apr 5, 2020
71bbd87
nixos/hardened: don't set kernel.unprivileged_bpf_disabled
emilazy Apr 4, 2020
af4f57b
nixos/hardened: don't set net.core.bpf_jit_harden
emilazy Apr 4, 2020
46d12cc
nixos/hardened: don't set vm.mmap_rnd{,_compat}_bits
emilazy Apr 5, 2020
cc28d51
nixos/hardened: don't set vm.mmap_min_addr
emilazy Apr 4, 2020
84f258b
nixos/hardened: don't set vm.unprivileged_userfaultfd
emilazy Apr 5, 2020
ad9bfe2
nixos/hardened: enable user namespaces for root
emilazy Apr 4, 2020
b0d5032
nixos/hardened: add emily to maintainers
emilazy Apr 4, 2020
fe031d0
nixos/tests/hardened: add latestKernel argument
emilazy Apr 4, 2020
e133e39
nixos/release-{small,combined}: add latestKernel.login
emilazy Apr 4, 2020
2e31fb4
nixos/release-combined: add {,latestKernel.}hardened
emilazy Apr 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 1 addition & 38 deletions nixos/modules/profiles/hardened.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ with lib;

{
meta = {
maintainers = [ maintainers.joachifm ];
maintainers = [ maintainers.joachifm maintainers.emily ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe one should mention in meta.doc = ./hardened.xml; that in order to use Firefox with this profile, one has to reset the memory allocator:

#73763 (comment)

cc @Flakebi

Copy link
Member Author

@emilazy emilazy Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed; not sure it belongs in this PR which is entirely kernel changes and already huge, though, as Firefox is broken with a custom allocator set regardless of what kernel you use. I think the correct solution to make Firefox work is to implement a library with replace-malloc hooks; I've been idly planning to do that since the scudo change got merged but I'd be very happy for someone to preempt me! It'd also be nice to have support for setting up Firefox's setuid sandbox like Chromium's if we're disabling unprivileged userns.

FWIW, from playing around with things I think the "graphene-hardened" allocator might have better compatibility for some programs than scudo (though it's a mixed bag – right now it flags up what looks like memory unsafety in nix(1)!), and it's what I was planning on targetting with the replace-malloc library, but ultimately I suspect that we're going to want a way to specifically exempt packages from the hardened allocator. With the current implementation that involves mount namespaces so you can hide /etc/ld-nix.so.preload, which combined with the userns defaults means that the wrappers to do it will need to be setuid root :(

Maybe we could patch the dynamic loader to ignore the preload file if there's a special marker in the ELF file or something.

};

boot.kernelPackages = mkDefault pkgs.linuxPackages_hardened;
Expand All @@ -21,8 +21,6 @@ with lib;

security.lockKernelModules = mkDefault true;

security.allowUserNamespaces = mkDefault false;

security.protectKernelImage = mkDefault true;

security.allowSimultaneousMultithreading = mkDefault false;
Expand All @@ -37,15 +35,9 @@ with lib;
# Slab/slub sanity checks, redzoning, and poisoning
"slub_debug=FZP"

# Disable slab merging to make certain heap overflow attacks harder
"slab_nomerge"

# Overwrite free'd memory
"page_poison=1"

# Disable legacy virtual syscalls
"vsyscall=none"

# Enable page allocator randomization
"page_alloc.shuffle=1"
];
Expand Down Expand Up @@ -82,38 +74,12 @@ with lib;
# (e.g., parent/child)
boot.kernel.sysctl."kernel.yama.ptrace_scope" = mkOverride 500 1;

# Restrict access to kernel ring buffer (information leaks)
boot.kernel.sysctl."kernel.dmesg_restrict" = mkDefault true;

# Hide kptrs even for processes with CAP_SYSLOG
boot.kernel.sysctl."kernel.kptr_restrict" = mkOverride 500 2;

# Unprivileged access to bpf() has been used for privilege escalation in
# the past
boot.kernel.sysctl."kernel.unprivileged_bpf_disabled" = mkDefault true;

# Disable bpf() JIT (to eliminate spray attacks)
boot.kernel.sysctl."net.core.bpf_jit_enable" = mkDefault false;

# ... or at least apply some hardening to it
boot.kernel.sysctl."net.core.bpf_jit_harden" = mkDefault true;

# Raise ASLR entropy for 64bit & 32bit, respectively.
#
# Note: mmap_rnd_compat_bits may not exist on 64bit.
boot.kernel.sysctl."vm.mmap_rnd_bits" = mkDefault 32;
boot.kernel.sysctl."vm.mmap_rnd_compat_bits" = mkDefault 16;

# Allowing users to mmap() memory starting at virtual address 0 can turn a
# NULL dereference bug in the kernel into code execution with elevated
# privilege. Mitigate by enforcing a minimum base addr beyond the NULL memory
# space. This breaks applications that require mapping the 0 page, such as
# dosemu or running 16bit applications under wine. It also breaks older
# versions of qemu.
#
# The value is taken from the KSPP recommendations (Debian uses 4096).
boot.kernel.sysctl."vm.mmap_min_addr" = mkDefault 65536;

# Disable ftrace debugging
boot.kernel.sysctl."kernel.ftrace_enabled" = mkDefault false;

Expand All @@ -140,7 +106,4 @@ with lib;
# Ignore outgoing ICMP redirects (this is ipv4 only)
boot.kernel.sysctl."net.ipv4.conf.all.send_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.send_redirects" = mkDefault false;

# Restrict userfaultfd syscalls to processes with the SYS_PTRACE capability
boot.kernel.sysctl."vm.unprivileged_userfaultfd" = mkDefault false;
}
3 changes: 3 additions & 0 deletions nixos/release-combined.nix
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ in rec {
(onFullSupported "nixos.tests.fontconfig-default-fonts")
(onFullSupported "nixos.tests.gnome3")
(onFullSupported "nixos.tests.gnome3-xorg")
(onFullSupported "nixos.tests.hardened")
(onSystems ["x86_64-linux"] "nixos.tests.hibernate")
(onFullSupported "nixos.tests.i3wm")
(onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSimple")
Expand All @@ -96,6 +97,8 @@ in rec {
(onFullSupported "nixos.tests.keymap.dvp")
(onFullSupported "nixos.tests.keymap.neo")
(onFullSupported "nixos.tests.keymap.qwertz")
(onFullSupported "nixos.tests.latestKernel.hardened")
(onFullSupported "nixos.tests.latestKernel.login")
(onFullSupported "nixos.tests.lightdm")
(onFullSupported "nixos.tests.login")
(onFullSupported "nixos.tests.misc")
Expand Down
1 change: 1 addition & 0 deletions nixos/release-small.nix
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ in rec {
"nixos.tests.installer.separateBoot.x86_64-linux"
"nixos.tests.installer.simple.x86_64-linux"
"nixos.tests.ipv6.x86_64-linux"
"nixos.tests.latestKernel.login.x86_64-linux"
"nixos.tests.login.x86_64-linux"
"nixos.tests.misc.x86_64-linux"
"nixos.tests.nat.firewall-conntrack.x86_64-linux"
Expand Down
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ in
# kubernetes.e2e should eventually replace kubernetes.rbac when it works
#kubernetes.e2e = handleTestOn ["x86_64-linux"] ./kubernetes/e2e.nix {};
kubernetes.rbac = handleTestOn ["x86_64-linux"] ./kubernetes/rbac.nix {};
latestKernel.hardened = handleTest ./hardened.nix { latestKernel = true; };
latestKernel.login = handleTest ./login.nix { latestKernel = true; };
ldap = handleTest ./ldap.nix {};
leaps = handleTest ./leaps.nix {};
Expand Down
11 changes: 8 additions & 3 deletions nixos/tests/hardened.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : {
import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : {
name = "hardened";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ joachifm ];
Expand All @@ -10,6 +10,8 @@ import ./make-test.nix ({ pkgs, ...} : {
{ users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; };
users.users.sybil = { isNormalUser = true; group = "wheel"; };
imports = [ ../modules/profiles/hardened.nix ];
boot.kernelPackages =
lib.mkIf latestKernel pkgs.linuxPackages_latest_hardened;
environment.memoryAllocator.provider = "graphene-hardened";
nix.useSandbox = false;
virtualisation.emptyDiskImages = [ 4096 ];
Expand All @@ -23,7 +25,9 @@ import ./make-test.nix ({ pkgs, ...} : {
options = [ "noauto" ];
};
};
boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
boot.extraModulePackages =
optional (versionOlder config.boot.kernelPackages.kernel.version "5.6")
config.boot.kernelPackages.wireguard;
boot.kernelModules = [ "wireguard" ];
};

Expand Down Expand Up @@ -76,7 +80,8 @@ import ./make-test.nix ({ pkgs, ...} : {

# Test userns
subtest "userns", sub {
$machine->fail("unshare --user");
$machine->succeed("unshare --user true");
$machine->fail("su -l alice -c 'unshare --user true'");
};

# Test dmesg restriction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ stdenv.mkDerivation rec {
'';
license = licenses.mit;
maintainers = with maintainers; [ ris ];
platforms = [ "x86_64-linux" ];
platforms = [ "x86_64-linux" "aarch64-linux" ];
};
}
Loading