Merge pull request #8654 from ts468/upstream.trusted_grub_integration

grub installation: integrate trustedGRUB + fix broken equality check

Changed files
+39 -7
nixos
modules
system
boot
+28 -1
nixos/modules/system/boot/loader/grub/grub.nix
···
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.,
···
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 "";
···
'';
};
+
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.
+
'';
+
};
+
};
};
···
{
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: [
{
+11 -6
nixos/modules/system/boot/loader/grub/install-grub.pl
···
#
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 = <FILE>;
+
chomp($name);
my $version = <FILE>;
chomp($version);
my $efi = <FILE>;
···
my $efiMountPoint = <FILE>;
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
}
···
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
···
# 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;