From 65cbbc75b0f9c91037c7eb8e82fea9a48fb2d96e Mon Sep 17 00:00:00 2001 From: Thomas Strobel Date: Sun, 5 Jul 2015 18:54:35 +0200 Subject: grub installation: integrate trustedGRUB + fix broken equality check --- nixos/modules/system/boot/loader/grub/grub.nix | 29 +++++++++++++++++++++- .../system/boot/loader/grub/install-grub.pl | 17 ++++++++----- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 3c879450ba6d..c7cf712e3c2b 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -10,7 +10,8 @@ let realGrub = if cfg.version == 1 then pkgs.grub else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; } - else pkgs.grub2; + else if cfg.enableTrustedboot then pkgs.trustedGrub + else pkgs.grub2; grub = # Don't include GRUB if we're only generating a GRUB menu (e.g., @@ -37,6 +38,7 @@ let grub = f grub; grubTarget = f (grub.grubTarget or ""); shell = "${pkgs.stdenv.shell}"; + fullName = (builtins.parseDrvName realGrub.name).name; fullVersion = (builtins.parseDrvName realGrub.name).version; grubEfi = f grubEfi; grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else ""; @@ -367,6 +369,15 @@ in ''; }; + enableTrustedboot = mkOption { + default = false; + type = types.bool; + description = '' + Enable trusted boot. Grub will measure all critical components during + the boot process to offer TCG (TPM) support. + ''; + }; + }; }; @@ -429,6 +440,22 @@ in assertion = all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters); message = "You cannot have duplicated devices in mirroredBoots"; } + { + assertion = !cfg.enableTrustedboot || cfg.version == 2; + message = "Trusted GRUB is only available for GRUB 2"; + } + { + assertion = !cfg.efiSupport || !cfg.enableTrustedboot; + message = "Trusted GRUB does not have EFI support"; + } + { + assertion = !cfg.zfsSupport || !cfg.enableTrustedboot; + message = "Trusted GRUB does not have ZFS support"; + } + { + assertion = !cfg.enableTrustedboot; + message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless."; + } ] ++ flip concatMap cfg.mirroredBoots (args: [ { assertion = args.devices != [ ]; diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index cad9013bf5ad..de0a4c7f0567 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -433,15 +433,18 @@ foreach my $fn (glob "$bootPath/kernels/*") { # struct(GrubState => { + name => '$', version => '$', efi => '$', devices => '$', efiMountPoint => '$', }); sub readGrubState { - my $defaultGrubState = GrubState->new(version => "", efi => "", devices => "", efiMountPoint => "" ); + my $defaultGrubState = GrubState->new(name => "", version => "", efi => "", devices => "", efiMountPoint => "" ); open FILE, "<$bootPath/grub/state" or return $defaultGrubState; local $/ = "\n"; + my $name = ; + chomp($name); my $version = ; chomp($version); my $efi = ; @@ -451,7 +454,7 @@ sub readGrubState { my $efiMountPoint = ; chomp($efiMountPoint); close FILE; - my $grubState = GrubState->new(version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint ); + my $grubState = GrubState->new(name => $name, version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint ); return $grubState } @@ -497,10 +500,11 @@ my $prevGrubState = readGrubState(); my @prevDeviceTargets = split/:/, $prevGrubState->devices; my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference() ); -my $versionDiffer = (get("fullVersion") eq \$prevGrubState->version); -my $efiDiffer = ($efiTarget eq \$prevGrubState->efi); -my $efiMountPointDiffer = ($efiSysMountPoint eq \$prevGrubState->efiMountPoint); -my $requireNewInstall = $devicesDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1"); +my $nameDiffer = !(get("fullName") eq $prevGrubState->name); +my $versionDiffer = !(get("fullVersion") eq $prevGrubState->version); +my $efiDiffer = !($efiTarget eq $prevGrubState->efi); +my $efiMountPointDiffer = !($efiSysMountPoint eq $prevGrubState->efiMountPoint); +my $requireNewInstall = $devicesDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1"); # install a symlink so that grub can detect the boot drive when set # as the root directory @@ -543,6 +547,7 @@ if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) # update GRUB state file if ($requireNewInstall != 0) { open FILE, ">$bootPath/grub/state" or die "cannot create $bootPath/grub/state: $!\n"; + print FILE get("fullName"), "\n" or die; print FILE get("fullVersion"), "\n" or die; print FILE $efiTarget, "\n" or die; print FILE join( ":", @deviceTargets ), "\n" or die; -- cgit 1.4.1