diff --git a/crates/boot/src/actions/chainload.rs b/crates/boot/src/actions/chainload.rs index 1753384..631e3af 100644 --- a/crates/boot/src/actions/chainload.rs +++ b/crates/boot/src/actions/chainload.rs @@ -15,24 +15,22 @@ use log::warn; use uefi::CString16; use uefi::proto::loaded_image::LoadedImage; -/// Read the Linux initrd at `path` relative to the sprout image. +/// Read the initrd at the stamped `path` relative to the sprout image. /// Provides [None] if the path refers to the root of a filesystem rather than a file. -fn read_linux_initrd(context: &Rc, path: &str) -> Result>> { +pub fn read_initrd(context: &Rc, path: &str) -> Result>> { let resolved = eficore::path::resolve_path(Some(context.root().loaded_image_path()?), path) - .context("unable to resolve linux initrd path")?; + .context("unable to resolve initrd path")?; // A path without a file component refers to the root of the filesystem, not an initrd. // This happens when a path template like "$root\\$initrd-0" is stamped with an empty // initrd value, such as a BLS entry without an initrd or an unused BLS initrd slot. let subpath = eficore::path::device_path_subpath(&resolved.full_path) - .context("unable to get linux initrd subpath")?; + .context("unable to get initrd subpath")?; if subpath.trim_matches('\\').is_empty() { return Ok(None); } - let content = resolved - .read_file() - .context("unable to read linux initrd")?; + let content = resolved.read_file().context("unable to read initrd")?; Ok(Some(content)) } @@ -108,7 +106,7 @@ pub fn chainload(context: Rc, configuration: &ChainloadConfigurat let Some(path) = empty_is_none(Some(path)) else { continue; }; - let Some(content) = read_linux_initrd(&context, &path)? else { + let Some(content) = read_initrd(&context, &path)? else { continue; }; match initrd.as_mut() { diff --git a/crates/boot/src/actions/edera.rs b/crates/boot/src/actions/edera.rs index d031d8d..641eb9d 100644 --- a/crates/boot/src/actions/edera.rs +++ b/crates/boot/src/actions/edera.rs @@ -87,18 +87,24 @@ pub fn edera(context: Rc, configuration: &EderaConfiguration) -> // Read the initrd, or each initrd in the chain concatenated in order, then // extend PCR 9 with the combined bytes (empty when no initrd is configured). + // Paths are stamped first, and paths that are empty after stamping or that refer + // to the root of a filesystem are skipped, the same as the chainload action. let mut initrd_bytes = Vec::new(); - for p in configuration + let initrd_paths = configuration .initrd .iter() .chain(configuration.initrd_chain.iter()) - { - if let Some(p) = empty_is_none(Some(p)) { - append_initrd( - &mut initrd_bytes, - &read_loader_payload(&context, "initrd", p)?, - ); - } + .map(|item| context.stamp(item)); + for path in initrd_paths { + let Some(path) = empty_is_none(Some(path)) else { + continue; + }; + let Some(content) = actions::chainload::read_initrd(&context, &path) + .context("unable to read initrd file")? + else { + continue; + }; + append_initrd(&mut initrd_bytes, &content); } PlatformTpm::log_event( PlatformTpm::PCR_INITRD,