Merge pull request #305 from nix-community/prepare-stub-for-dynamic-initrds

stub(*): support dynamic initrds
This commit is contained in:
Ryan Lahfa 2024-03-01 08:24:07 +00:00 committed by GitHub
commit 614b538f0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 7 deletions

View File

@ -39,14 +39,18 @@ impl EmbeddedConfiguration {
}
}
pub fn boot_linux(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
pub fn boot_linux(
handle: Handle,
mut system_table: SystemTable<Boot>,
dynamic_initrds: Vec<Vec<u8>>,
) -> Status {
uefi_services::init(&mut system_table).unwrap();
// SAFETY: We get a slice that represents our currently running
// image and then parse the PE data structures from it. This is
// safe, because we don't touch any data in the data sections that
// might conceivably change while we look at the slice.
let config = unsafe {
let mut config = unsafe {
EmbeddedConfiguration::new(
booted_image_file(system_table.boot_services())
.unwrap()
@ -62,5 +66,16 @@ pub fn boot_linux(handle: Handle, mut system_table: SystemTable<Boot>) -> Status
secure_boot_enabled,
);
boot_linux_unchecked(handle, system_table, config.kernel, &cmdline, config.initrd).status()
let mut final_initrd = Vec::new();
final_initrd.append(&mut config.initrd);
// Correctness: dynamic initrds are supposed to be validated by caller,
// i.e. they are system extension images or credentials
// that are supposedly measured in TPM2.
// Therefore, it is normal to not verify their hashes against a configuration.
for mut extra_initrd in dynamic_initrds {
final_initrd.append(&mut extra_initrd);
}
boot_linux_unchecked(handle, system_table, config.kernel, &cmdline, final_initrd).status()
}

View File

@ -15,6 +15,7 @@ mod thin;
#[cfg(all(feature = "fat", feature = "thin"))]
compile_error!("A thin and fat stub cannot be produced at the same time, disable either `thin` or `fat` feature");
use alloc::vec::Vec;
use linux_bootloader::efivars::{export_efi_variables, get_loader_features, EfiLoaderFeatures};
use linux_bootloader::measure::measure_image;
use linux_bootloader::tpm::tpm_available;
@ -69,15 +70,18 @@ fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
export_efi_variables(STUB_NAME, &system_table).expect("Failed to export stub EFI variables");
let status;
// A list of dynamically assembled initrds, e.g. credential initrds or system extension
// initrds.
let dynamic_initrds: Vec<Vec<u8>> = Vec::new();
#[cfg(feature = "fat")]
{
status = fat::boot_linux(handle, system_table)
status = fat::boot_linux(handle, system_table, dynamic_initrds)
}
#[cfg(feature = "thin")]
{
status = thin::boot_linux(handle, system_table).status()
status = thin::boot_linux(handle, system_table, dynamic_initrds).status()
}
status

View File

@ -1,3 +1,4 @@
use alloc::vec::Vec;
use log::{error, warn};
use sha2::{Digest, Sha256};
use uefi::{fs::FileSystem, prelude::*, CString16, Result};
@ -75,7 +76,11 @@ fn check_hash(data: &[u8], expected_hash: Hash, name: &str, secure_boot: bool) -
Ok(())
}
pub fn boot_linux(handle: Handle, mut system_table: SystemTable<Boot>) -> uefi::Result<()> {
pub fn boot_linux(
handle: Handle,
mut system_table: SystemTable<Boot>,
dynamic_initrds: Vec<Vec<u8>>,
) -> uefi::Result<()> {
uefi_services::init(&mut system_table).unwrap();
// SAFETY: We get a slice that represents our currently running
@ -94,7 +99,7 @@ pub fn boot_linux(handle: Handle, mut system_table: SystemTable<Boot>) -> uefi::
let secure_boot_enabled = get_secure_boot_status(system_table.runtime_services());
let kernel_data;
let initrd_data;
let mut initrd_data;
{
let file_system = system_table
@ -130,5 +135,13 @@ pub fn boot_linux(handle: Handle, mut system_table: SystemTable<Boot>) -> uefi::
secure_boot_enabled,
)?;
// Correctness: dynamic initrds are supposed to be validated by caller,
// i.e. they are system extension images or credentials
// that are supposedly measured in TPM2.
// Therefore, it is normal to not verify their hashes against a configuration.
for mut extra_initrd in dynamic_initrds {
initrd_data.append(&mut extra_initrd);
}
boot_linux_unchecked(handle, system_table, kernel_data, &cmdline, initrd_data)
}