fix(chainload): skip initrd paths without a file component

Autoconfigured BLS actions use "$root\\$initrd" as the initrd path.
For BLS entries without an initrd line this stamps to the root of the
filesystem, and Sprout tried to read that directory as the initrd,
failing the boot. Treat a path that resolves to no file as no initrd.
This commit is contained in:
alex authored and Alex Zenla committed 2026-09-26 18:58:54 -07:00
1 parent 9967a7ab80
commit 6f84a1014a
1 file changed
+20 -9
+20 -9
View File
@@ -77,15 +77,26 @@ pub fn chainload(context: Rc<SproutContext>, configuration: &ChainloadConfigurat
// If an initrd is provided, register it with the EFI stack.
let mut initrd_handle = None;
if let Some(linux_initrd) = initrd {
let content = eficore::path::read_file_contents(
Some(context.root().loaded_image_path()?),
&linux_initrd,
)
.context("unable to read linux initrd")?;
let handle =
MediaLoaderHandle::register(LINUX_EFI_INITRD_MEDIA_GUID, content.into_boxed_slice())
.context("unable to register linux initrd")?;
initrd_handle = Some(handle);
let resolved_initrd =
eficore::path::resolve_path(Some(context.root().loaded_image_path()?), &linux_initrd)
.context("unable to resolve linux 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" is stamped with an empty
// initrd value, such as a BLS entry without an initrd.
let initrd_subpath = eficore::path::device_path_subpath(&resolved_initrd.full_path)
.context("unable to get linux initrd subpath")?;
if !initrd_subpath.trim_matches('\\').is_empty() {
let content = resolved_initrd
.read_file()
.context("unable to read linux initrd")?;
let handle = MediaLoaderHandle::register(
LINUX_EFI_INITRD_MEDIA_GUID,
content.into_boxed_slice(),
)
.context("unable to register linux initrd")?;
initrd_handle = Some(handle);
}
}
// Mark execution of an entry in the bootloader interface.