-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Description
Describe the solution you'd like
#2587 added support for measuring the kernel command line into the TPM. This is to allow for "Measured Boot" where all components of the boot chain (firmware, bootloader, kernel, etc..) are measured into the TPM for later cryptographic attestation. However, that patch didn't include measuring a key component of the boot chain: the initrd. #6124 attempted to add this support, but @haraldh correctly pointed out that it doesn't make sense to measure the disk and then have the kernel reload the initrd from disk, as this is quite insecure.
It's worth looking at how @mjg59's Grub patches handle this. For context, the Linux kernel has two entry points:
- EFISTUB: the standard UEFI entry point
- This allows the kernel bzImage to masquerade as a normal EFI binary
- It has the magic
initrdcommand line parameter - Used by systemd-boot when using normal
boot.ccode - Used by Grub with
chainloader
- EFI handover:
- Similar to the other kernel entry points, you set the
bootparamsstruct (née Zero Page) and jump to an address. - Requires bootloader to load initrds into memory before jumping
- Used by systemd-boot when using
shim.ccode - Used by (non-mainline) Grub with
linuxefi.
- Similar to the other kernel entry points, you set the
In Matthew's patches to GRUB, the command line params can be measured into PCR 8 (like systemd-boot) and the initrds can be measured into PCR 9 (unlike systemd-boot) when the kernel is loaded with linuxefi.
My proposal is two-fold:
- If a systemd-boot loader entry uses
linuxandinitrdparameters, we load the kernel using the EFI handover protocol, similar to what we already do in the stub code. - If the
tpmoption is enabled, measure any initrds into the TPM. Which PCR would be determined by ainitrd-pcrindexoption, defaulting to PCR 9.
Advantages to this approach
- Linux is always loaded the same way with systemd-boot. We would use the EFI handover entry point for the normal bootloader and the stub.
- The PCR measurements are similar between Grub and systemd-boot. This makes it easier for users who only care about UEFI/Secure Boot/Measured Boot to switch to systemd-boot.
- Almost all the code already exists in systemd-boot, due to the existence of the stub.
Questions for @haraldh
- If I submitted a PR for (1) or (2), would you consider merging it?
- Would you want the changes in (1) to be the new default, or have it be behind either a compile-time flag or an additional field in the entry file?
Describe alternatives you've considered
- Load initrd(s) from disk and don't measure them (current situation)
- Not measuring the initramfs defeats the point of measuring anything, as it isn't possible to verify that the boot chain is uncompromised (an attacker can just swap out the initramfs and compromise the system).
- Embed initrd, cmdline, kernel in the systemd-boot EFI image
- This is the current point of systemd-boot stub functionality. However, this is not an option if the initramfs needs to be it's own separate file. Most distros rely on the initrmfs to:
- update out of band with the kernel
- be customized for each user's machine
- This is the current point of systemd-boot stub functionality. However, this is not an option if the initramfs needs to be it's own separate file. Most distros rely on the initrmfs to:
- Have the kernel measure the initrd(s) when when it loads them.
- Note that the kernel would have to do this in the EFI stub code before that code jumps to the handover entry point.
- As described above, Grub (with
linuxefisupport) already measures the initrd(s) into PCR 9, if we also added this functionality to the kernel, we would measure the initrd(s) twice unless we were very careful with our versions and configurations.