diff --git a/rust/stub/src/main.rs b/rust/stub/src/main.rs index da26155..adf4c4a 100644 --- a/rust/stub/src/main.rs +++ b/rust/stub/src/main.rs @@ -25,7 +25,7 @@ use uefi::{ use crate::{ linux_loader::InitrdLoader, - uefi_helpers::{booted_image_cmdline, booted_image_file, read_all}, + uefi_helpers::{booted_image_file, read_all}, }; type Hash = sha2::digest::Output; @@ -67,13 +67,16 @@ struct EmbeddedConfiguration { /// The cryptographic hash of the initrd. This hash is computed /// over the whole PE binary, not only the embedded initrd. initrd_hash: Hash, + + /// The kernel command-line. + cmdline: CString16, } -/// Extract a filename from a PE section. The filename is stored as UTF-8. -fn extract_filename(file_data: &[u8], section: &str) -> Result { - let filename = pe_section_as_string(file_data, section).ok_or(Status::INVALID_PARAMETER)?; +/// Extract a string, stored as UTF-8, from a PE section. +fn extract_string(file_data: &[u8], section: &str) -> Result { + let string = pe_section_as_string(file_data, section).ok_or(Status::INVALID_PARAMETER)?; - Ok(CString16::try_from(filename.as_str()).map_err(|_| Status::INVALID_PARAMETER)?) + Ok(CString16::try_from(string.as_str()).map_err(|_| Status::INVALID_PARAMETER)?) } /// Extract a Blake3 hash from a PE section. @@ -92,11 +95,13 @@ impl EmbeddedConfiguration { let file_data = read_all(file)?; Ok(Self { - kernel_filename: extract_filename(&file_data, ".kernelp")?, + kernel_filename: extract_string(&file_data, ".kernelp")?, kernel_hash: extract_hash(&file_data, ".kernelh")?, - initrd_filename: extract_filename(&file_data, ".initrdp")?, + initrd_filename: extract_string(&file_data, ".initrdp")?, initrd_hash: extract_hash(&file_data, ".initrdh")?, + + cmdline: extract_string(&file_data, ".cmdline")?, }) } } @@ -164,16 +169,13 @@ fn main(handle: Handle, mut system_table: SystemTable) -> Status { return Status::SECURITY_VIOLATION; } - let kernel_cmdline = - booted_image_cmdline(system_table.boot_services()).expect("Failed to fetch command line"); - let kernel = Image::load(system_table.boot_services(), &kernel_data).expect("Failed to load the kernel"); let mut initrd_loader = InitrdLoader::new(system_table.boot_services(), handle, initrd_data) .expect("Failed to load the initrd. It may not be there or it is not signed"); - let status = unsafe { kernel.start(handle, &system_table, &kernel_cmdline) }; + let status = unsafe { kernel.start(handle, &system_table, &config.cmdline) }; initrd_loader .uninstall(system_table.boot_services()) diff --git a/rust/stub/src/pe_loader.rs b/rust/stub/src/pe_loader.rs index 9ce5305..b60faaa 100644 --- a/rust/stub/src/pe_loader.rs +++ b/rust/stub/src/pe_loader.rs @@ -9,7 +9,7 @@ use uefi::{ boot::{AllocateType, MemoryType}, Boot, SystemTable, }, - Handle, Status, + CStr16, Handle, Status, }; /// UEFI mandates 4 KiB pages. @@ -124,7 +124,7 @@ impl Image { self, handle: Handle, system_table: &SystemTable, - load_options: &[u8], + load_options: &CStr16, ) -> Status { let mut loaded_image = system_table .boot_services() @@ -146,7 +146,7 @@ impl Image { ); loaded_image.set_load_options( load_options.as_ptr() as *const u8, - u32::try_from(load_options.len()).unwrap(), + u32::try_from(load_options.num_bytes()).unwrap(), ); } diff --git a/rust/stub/src/uefi_helpers.rs b/rust/stub/src/uefi_helpers.rs index a2585f7..7bb374b 100644 --- a/rust/stub/src/uefi_helpers.rs +++ b/rust/stub/src/uefi_helpers.rs @@ -56,15 +56,3 @@ pub fn booted_image_file(boot_services: &BootServices) -> Result { .into_regular_file() .ok_or(Status::INVALID_PARAMETER)?) } - -/// Return the command line of the currently executing image. -pub fn booted_image_cmdline(boot_services: &BootServices) -> Result> { - let loaded_image = - boot_services.open_protocol_exclusive::(boot_services.image_handle())?; - - Ok(loaded_image - // If this fails, we have no load options and we return an empty string. - .load_options_as_bytes() - .map(|b| b.to_vec()) - .unwrap_or_default()) -}