| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  | import ./make-test.nix ({ pkgs, ...} : { | 
					
						
							|  |  |  |   name = "hardened"; | 
					
						
							|  |  |  |   meta = with pkgs.stdenv.lib.maintainers; { | 
					
						
							|  |  |  |     maintainers = [ joachifm ]; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   machine = | 
					
						
							| 
									
										
										
										
											2019-01-06 13:17:38 +01:00
										 |  |  |     { lib, pkgs, config, ... }: | 
					
						
							| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  |     with lib; | 
					
						
							|  |  |  |     { users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; }; | 
					
						
							|  |  |  |       users.users.sybil = { isNormalUser = true; group = "wheel"; }; | 
					
						
							|  |  |  |       imports = [ ../modules/profiles/hardened.nix ]; | 
					
						
							| 
									
										
										
										
											2019-09-18 15:34:56 +02:00
										 |  |  |       environment.memoryAllocator.provider = "graphene-hardened"; | 
					
						
							| 
									
										
										
										
											2018-11-24 14:57:50 +01:00
										 |  |  |       nix.useSandbox = false; | 
					
						
							| 
									
										
										
										
											2017-09-22 23:20:42 +02:00
										 |  |  |       virtualisation.emptyDiskImages = [ 4096 ]; | 
					
						
							|  |  |  |       boot.initrd.postDeviceCommands = ''
 | 
					
						
							|  |  |  |         ${pkgs.dosfstools}/bin/mkfs.vfat -n EFISYS /dev/vdb | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |       fileSystems = lib.mkVMOverride { | 
					
						
							|  |  |  |         "/efi" = { | 
					
						
							|  |  |  |           device = "/dev/disk/by-label/EFISYS"; | 
					
						
							|  |  |  |           fsType = "vfat"; | 
					
						
							|  |  |  |           options = [ "noauto" ]; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2019-01-06 13:17:38 +01:00
										 |  |  |       boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ]; | 
					
						
							|  |  |  |       boot.kernelModules = [ "wireguard" ]; | 
					
						
							| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   testScript = | 
					
						
							| 
									
										
										
										
											2019-04-23 22:24:16 +02:00
										 |  |  |     let | 
					
						
							| 
									
										
										
										
											2019-08-13 21:52:01 +00:00
										 |  |  |       hardened-malloc-tests = pkgs.stdenv.mkDerivation { | 
					
						
							| 
									
										
										
										
											2019-04-23 22:24:16 +02:00
										 |  |  |         name = "hardened-malloc-tests-${pkgs.graphene-hardened-malloc.version}"; | 
					
						
							|  |  |  |         src = pkgs.graphene-hardened-malloc.src; | 
					
						
							|  |  |  |         buildPhase = ''
 | 
					
						
							|  |  |  |           cd test/simple-memory-corruption | 
					
						
							|  |  |  |           make -j4 | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         installPhase = ''
 | 
					
						
							|  |  |  |           find . -type f -executable -exec install -Dt $out/bin '{}' + | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     in | 
					
						
							| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  |     ''
 | 
					
						
							| 
									
										
										
										
											2018-05-19 08:42:15 +02:00
										 |  |  |       $machine->waitForUnit("multi-user.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-11 18:20:41 +02:00
										 |  |  |       subtest "apparmor-loaded", sub { | 
					
						
							|  |  |  |           $machine->succeed("systemctl status apparmor.service"); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # AppArmor securityfs | 
					
						
							|  |  |  |       subtest "apparmor-securityfs", sub { | 
					
						
							|  |  |  |           $machine->succeed("mountpoint -q /sys/kernel/security"); | 
					
						
							|  |  |  |           $machine->succeed("cat /sys/kernel/security/apparmor/profiles"); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-06 13:17:38 +01:00
										 |  |  |       # Test loading out-of-tree modules | 
					
						
							|  |  |  |       subtest "extra-module-packages", sub { | 
					
						
							|  |  |  |           $machine->succeed("grep -Fq wireguard /proc/modules"); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  |       # Test hidepid | 
					
						
							|  |  |  |       subtest "hidepid", sub { | 
					
						
							|  |  |  |           $machine->succeed("grep -Fq hidepid=2 /proc/mounts"); | 
					
						
							| 
									
										
										
										
											2018-05-19 08:42:15 +02:00
										 |  |  |           # cannot use pgrep -u here, it segfaults when access to process info is denied | 
					
						
							|  |  |  |           $machine->succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]"); | 
					
						
							|  |  |  |           $machine->succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]"); | 
					
						
							| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Test kernel module hardening | 
					
						
							|  |  |  |       subtest "lock-modules", sub { | 
					
						
							|  |  |  |           # note: this better a be module we normally wouldn't load ... | 
					
						
							|  |  |  |           $machine->fail("modprobe dccp"); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-04-30 14:41:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Test userns | 
					
						
							|  |  |  |       subtest "userns", sub { | 
					
						
							|  |  |  |           $machine->fail("unshare --user"); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-09-16 11:46:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Test dmesg restriction | 
					
						
							|  |  |  |       subtest "dmesg", sub { | 
					
						
							|  |  |  |           $machine->fail("su -l alice -c dmesg"); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Test access to kcore | 
					
						
							|  |  |  |       subtest "kcore", sub { | 
					
						
							|  |  |  |           $machine->fail("cat /proc/kcore"); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-09-22 23:20:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Test deferred mount | 
					
						
							|  |  |  |       subtest "mount", sub { | 
					
						
							|  |  |  |         $machine->fail("mountpoint -q /efi"); # was deferred | 
					
						
							|  |  |  |         $machine->execute("mkdir -p /efi"); | 
					
						
							|  |  |  |         $machine->succeed("mount /dev/disk/by-label/EFISYS /efi"); | 
					
						
							|  |  |  |         $machine->succeed("mountpoint -q /efi"); # now mounted | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-11-24 15:13:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Test Nix dæmon usage | 
					
						
							|  |  |  |       subtest "nix-daemon", sub { | 
					
						
							|  |  |  |         $machine->fail("su -l nobody -s /bin/sh -c 'nix ping-store'"); | 
					
						
							|  |  |  |         $machine->succeed("su -l alice -c 'nix ping-store'") =~ "OK"; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-12-16 10:37:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Test kernel image protection | 
					
						
							|  |  |  |       subtest "kernelimage", sub { | 
					
						
							|  |  |  |         $machine->fail("systemctl hibernate"); | 
					
						
							|  |  |  |         $machine->fail("systemctl kexec"); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2019-04-23 22:24:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Test hardened memory allocator | 
					
						
							|  |  |  |       sub runMallocTestProg { | 
					
						
							|  |  |  |           my ($progName, $errorText) = @_; | 
					
						
							|  |  |  |           my $text = "fatal allocator error: " . $errorText; | 
					
						
							|  |  |  |           $machine->fail("${hardened-malloc-tests}/bin/" . $progName) =~ $text; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       subtest "hardenedmalloc", sub { | 
					
						
							|  |  |  |         runMallocTestProg("double_free_large", "invalid free"); | 
					
						
							|  |  |  |         runMallocTestProg("unaligned_free_small", "invalid unaligned free"); | 
					
						
							|  |  |  |         runMallocTestProg("write_after_free_small", "detected write after free"); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-04-30 08:38:47 +02:00
										 |  |  |     '';
 | 
					
						
							|  |  |  | }) |