From 9931e078191c557d609863a8f1c1a068dde8447d Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 2 Jun 2023 20:40:58 +0200 Subject: [PATCH] uefi: Fix wrong install_configuration_table() signature Interestingly, this crashes on aarch64 but works on x86_64. Likely, the x86_64 calling convention used still passes the Guid struct by pointer, while the aarch64 passes it by value (or in an unexpected registers) causing a crash. This also adds a test case to verify this works correctly now. Fixes: #842 --- uefi-test-runner/src/boot/misc.rs | 34 ++++++++++++++++++++++++++++--- uefi-test-runner/src/boot/mod.rs | 6 ++++-- uefi-test-runner/src/main.rs | 2 +- uefi/src/table/boot.rs | 4 ++-- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/uefi-test-runner/src/boot/misc.rs b/uefi-test-runner/src/boot/misc.rs index dfe0c6895..21d1a6d49 100644 --- a/uefi-test-runner/src/boot/misc.rs +++ b/uefi-test-runner/src/boot/misc.rs @@ -2,10 +2,12 @@ use core::ffi::c_void; use core::ptr::{self, NonNull}; use uefi::proto::unsafe_protocol; -use uefi::table::boot::{BootServices, EventType, SearchType, TimerTrigger, Tpl}; -use uefi::{Event, Identify}; +use uefi::table::boot::{BootServices, EventType, MemoryType, SearchType, TimerTrigger, Tpl}; +use uefi::table::{Boot, SystemTable}; +use uefi::{guid, Event, Guid, Identify}; -pub fn test(bt: &BootServices) { +pub fn test(st: &SystemTable) { + let bt = st.boot_services(); info!("Testing timer..."); test_timer(bt); info!("Testing events..."); @@ -18,6 +20,7 @@ pub fn test(bt: &BootServices) { test_install_protocol_interface(bt); test_reinstall_protocol_interface(bt); test_uninstall_protocol_interface(bt); + test_install_configuration_table(st); } fn test_timer(bt: &BootServices) { @@ -143,3 +146,28 @@ fn test_uninstall_protocol_interface(bt: &BootServices) { .expect("Failed to uninstall protocol interface"); } } + +fn test_install_configuration_table(st: &SystemTable) { + let config = st + .boot_services() + .allocate_pool(MemoryType::ACPI_RECLAIM, 1) + .expect("Failed to allocate config table"); + unsafe { config.write(42) }; + + let count = st.config_table().len(); + const ID: Guid = guid!("3bdb3089-5662-42df-840e-3922ed6467c9"); + + unsafe { + st.boot_services() + .install_configuration_table(&ID, config.cast()) + .expect("Failed to install configuration table"); + } + + assert_eq!(count + 1, st.config_table().len()); + let config_entry = st + .config_table() + .iter() + .find(|ct| ct.guid == ID) + .expect("Failed to find test config table"); + assert_eq!(unsafe { *(config_entry.address as *const u8) }, 42); +} diff --git a/uefi-test-runner/src/boot/mod.rs b/uefi-test-runner/src/boot/mod.rs index b17468357..cee4c3635 100644 --- a/uefi-test-runner/src/boot/mod.rs +++ b/uefi-test-runner/src/boot/mod.rs @@ -1,11 +1,13 @@ use uefi::proto::console::text::Output; use uefi::table::boot::{BootServices, SearchType}; +use uefi::table::{Boot, SystemTable}; use uefi::Identify; -pub fn test(bt: &BootServices) { +pub fn test(st: &SystemTable) { + let bt = st.boot_services(); info!("Testing boot services"); memory::test(bt); - misc::test(bt); + misc::test(st); test_locate_handle_buffer(bt); } diff --git a/uefi-test-runner/src/main.rs b/uefi-test-runner/src/main.rs index 5ddd97c0f..97d79d37e 100644 --- a/uefi-test-runner/src/main.rs +++ b/uefi-test-runner/src/main.rs @@ -49,7 +49,7 @@ fn efi_main(image: Handle, mut st: SystemTable) -> Status { bt.get_image_file_system(image) .expect("Failed to retrieve boot file system"); - boot::test(bt); + boot::test(&st); // Test all the supported protocols. proto::test(image, &mut st); diff --git a/uefi/src/table/boot.rs b/uefi/src/table/boot.rs index b53f9f349..07e1acace 100644 --- a/uefi/src/table/boot.rs +++ b/uefi/src/table/boot.rs @@ -174,7 +174,7 @@ pub struct BootServices { out_handle: &mut MaybeUninit, ) -> Status, install_configuration_table: - extern "efiapi" fn(guid_entry: Guid, table_ptr: *const c_void) -> Status, + extern "efiapi" fn(guid_entry: &Guid, table_ptr: *const c_void) -> Status, // Image services load_image: unsafe extern "efiapi" fn( @@ -1161,7 +1161,7 @@ impl BootServices { /// * [`uefi::Status::OUT_OF_RESOURCES`] pub unsafe fn install_configuration_table( &self, - guid_entry: Guid, + guid_entry: &Guid, table_ptr: *const c_void, ) -> Result { (self.install_configuration_table)(guid_entry, table_ptr).to_result()