Skip to content

Commit 04a0037

Browse files
committed
uefi-services: Return event in init
As mentioned in #917 If the app built with uefi-services exits before ExitBootServices, UEFI will call `UnloadImage` on it. Then the callback function is not in memory anymore and when ExitBootServices runs, invalid memory is accessed. QEMU will crash like this when the Linux EFISTUB calls ExitBootServices: ``` !!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!! RIP - 000000003E13F018, CS - 0000000000000038, RFLAGS - 0000000000210246 RAX - 0000000000000000, RCX - 000000003E191E98, RDX - 0000000000000000 RBX - 0000000000000004, RSP - 000000003FF0FD08, RBP - 000000003FF28740 RSI - 000000003E167518, RDI - 000000003FF6A5E0 R8 - 000000003FF27140, R9 - 000000003F4807A0, R10 - 0000000000000001 R11 - 00000000000000E1, R12 - 000000003E191EE0, R13 - 0000000000000100 R14 - 000000003FF28840, R15 - 000000003E191E98 DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030 GS - 0000000000000030, SS - 0000000000000030 CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 000000003FC01000 CR4 - 0000000000000668, CR8 - 0000000000000000 DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000 DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400 GDTR - 000000003F9DE000 0000000000000047, LDTR - 0000000000000000 IDTR - 000000003F471018 0000000000000FFF, TR - 0000000000000000 FXSAVE_STATE - 000000003FF0F960 !!!! Find image based on IP(0x3E13F018) (No PDB) (ImageBase=000000003DF1E000, EntryPoint=000000003DF1F000) !!!! ``` To avoid the crash, the user should close the event before the app exits. ```rs fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status { let event: Option<Event> = uefi_services::init(&mut system_table).unwrap(); let boot_services = system_table.boot_services(); println!("Hello World"); if let Some(event) = event { // Will creash when Linux boots if we don't call this boot_services.close_event(event).unwrap(); } Status::SUCCESS } ``` It would be nice to have this happen automatically by a Drop implementation but this already lets users do it on their own, if they need. Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent a07e961 commit 04a0037

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

uefi-services/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ pub fn system_table() -> NonNull<SystemTable<Boot>> {
7878
///
7979
/// This must be called as early as possible,
8080
/// before trying to use logging or memory allocation capabilities.
81-
pub fn init(st: &mut SystemTable<Boot>) -> Result {
81+
pub fn init(st: &mut SystemTable<Boot>) -> Result<Option<Event>> {
8282
unsafe {
8383
// Avoid double initialization.
8484
if SYSTEM_TABLE.is_some() {
85-
return Status::SUCCESS.to_result();
85+
return Status::SUCCESS.to_result_with_val(|| None);
8686
}
8787

8888
// Setup the system table singleton
@@ -104,7 +104,7 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result {
104104
Some(exit_boot_services),
105105
None,
106106
)
107-
.map(|_| ())
107+
.map(|e| Some(e))
108108
}
109109
}
110110

0 commit comments

Comments
 (0)