mirror of
https://github.com/edera-dev/sprout.git
synced 2026-11-04 17:52:20 +00:00
fix(edera): stamp initrd paths before skipping empty ones
The edera action checked whether an initrd path was empty before stamping it, so a path like "$initrd" that stamped to an empty value was still read, which failed and aborted boot. Stamp the paths first, and skip paths that stamp to the root of a filesystem, the same as the chainload action.
This commit is contained in:
1 parent
e96a5a64c9
commit
a77803dfe8
2 files changed
+20
-16
No files matched your search
@@ -15,24 +15,22 @@ use log::warn;
|
|||||||
use uefi::CString16;
|
use uefi::CString16;
|
||||||
use uefi::proto::loaded_image::LoadedImage;
|
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.
|
/// Provides [None] if the path refers to the root of a filesystem rather than a file.
|
||||||
fn read_linux_initrd(context: &Rc<SproutContext>, path: &str) -> Result<Option<Vec<u8>>> {
|
pub fn read_initrd(context: &Rc<SproutContext>, path: &str) -> Result<Option<Vec<u8>>> {
|
||||||
let resolved = eficore::path::resolve_path(Some(context.root().loaded_image_path()?), path)
|
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.
|
// 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
|
// 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.
|
// 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)
|
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() {
|
if subpath.trim_matches('\\').is_empty() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = resolved
|
let content = resolved.read_file().context("unable to read initrd")?;
|
||||||
.read_file()
|
|
||||||
.context("unable to read linux initrd")?;
|
|
||||||
Ok(Some(content))
|
Ok(Some(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +106,7 @@ pub fn chainload(context: Rc<SproutContext>, configuration: &ChainloadConfigurat
|
|||||||
let Some(path) = empty_is_none(Some(path)) else {
|
let Some(path) = empty_is_none(Some(path)) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Some(content) = read_linux_initrd(&context, &path)? else {
|
let Some(content) = read_initrd(&context, &path)? else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
match initrd.as_mut() {
|
match initrd.as_mut() {
|
||||||
|
|||||||
@@ -87,18 +87,24 @@ pub fn edera(context: Rc<SproutContext>, configuration: &EderaConfiguration) ->
|
|||||||
|
|
||||||
// Read the initrd, or each initrd in the chain concatenated in order, then
|
// 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).
|
// 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();
|
let mut initrd_bytes = Vec::new();
|
||||||
for p in configuration
|
let initrd_paths = configuration
|
||||||
.initrd
|
.initrd
|
||||||
.iter()
|
.iter()
|
||||||
.chain(configuration.initrd_chain.iter())
|
.chain(configuration.initrd_chain.iter())
|
||||||
{
|
.map(|item| context.stamp(item));
|
||||||
if let Some(p) = empty_is_none(Some(p)) {
|
for path in initrd_paths {
|
||||||
append_initrd(
|
let Some(path) = empty_is_none(Some(path)) else {
|
||||||
&mut initrd_bytes,
|
continue;
|
||||||
&read_loader_payload(&context, "initrd", p)?,
|
};
|
||||||
);
|
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::log_event(
|
||||||
PlatformTpm::PCR_INITRD,
|
PlatformTpm::PCR_INITRD,
|
||||||
|
|||||||
Reference in new issue
Block a user