Skip to content

Commit 71c6296

Browse files
committed
Fixes from PR
- Update system table crc32 - Fix unsound use of Box - Free exit data Signed-off-by: Ayush Singh <[email protected]>
1 parent b7b6bce commit 71c6296

File tree

1 file changed

+54
-18
lines changed

1 file changed

+54
-18
lines changed

library/std/src/sys/pal/uefi/process.rs

+54-18
Original file line numberDiff line numberDiff line change
@@ -382,36 +382,43 @@ mod uefi_command_internal {
382382

383383
let loaded_image: NonNull<loaded_image::Protocol> =
384384
helpers::open_protocol(child_handle, loaded_image::PROTOCOL_GUID).unwrap();
385-
let mut st: Box<r_efi::efi::SystemTable> =
385+
let st: Box<r_efi::efi::SystemTable> =
386386
Box::new(unsafe { crate::ptr::read((*loaded_image.as_ptr()).system_table) });
387387

388-
unsafe {
389-
(*loaded_image.as_ptr()).system_table = st.as_mut();
390-
}
391-
392388
Ok(Self::new(child_handle, st))
393389
}
394390
}
395391

396-
pub fn start_image(&self) -> io::Result<r_efi::efi::Status> {
392+
pub fn start_image(&mut self) -> io::Result<r_efi::efi::Status> {
393+
self.update_st_crc32()?;
394+
395+
// Use our system table instead of the default one
396+
let loaded_image: NonNull<loaded_image::Protocol> =
397+
helpers::open_protocol(self.handle, loaded_image::PROTOCOL_GUID).unwrap();
398+
unsafe {
399+
(*loaded_image.as_ptr()).system_table = self.st.as_mut();
400+
}
401+
397402
let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
398403
.ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
399404
.cast();
400-
let mut exit_data_size: MaybeUninit<usize> = MaybeUninit::uninit();
405+
let mut exit_data_size: usize = 0;
401406
let mut exit_data: MaybeUninit<*mut u16> = MaybeUninit::uninit();
402407

403408
let r = unsafe {
404409
((*boot_services.as_ptr()).start_image)(
405410
self.handle.as_ptr(),
406-
exit_data_size.as_mut_ptr(),
411+
&mut exit_data_size,
407412
exit_data.as_mut_ptr(),
408413
)
409414
};
410415

411416
// Drop exitdata
412-
unsafe {
413-
exit_data_size.assume_init_drop();
414-
exit_data.assume_init_drop();
417+
if exit_data_size != 0 {
418+
unsafe {
419+
let exit_data = exit_data.assume_init();
420+
((*boot_services.as_ptr()).free_pool)(exit_data as *mut crate::ffi::c_void);
421+
}
415422
}
416423

417424
Ok(r)
@@ -476,6 +483,30 @@ mod uefi_command_internal {
476483

477484
self.args = Some(args);
478485
}
486+
487+
fn update_st_crc32(&mut self) -> io::Result<()> {
488+
let bt: NonNull<r_efi::efi::BootServices> = boot_services().unwrap().cast();
489+
let st_size = self.st.hdr.header_size as usize;
490+
let mut crc32: u32 = 0;
491+
492+
// Set crc to 0 before calcuation
493+
self.st.hdr.crc32 = 0;
494+
495+
let r = unsafe {
496+
((*bt.as_ptr()).calculate_crc32)(
497+
self.st.as_mut() as *mut r_efi::efi::SystemTable as *mut crate::ffi::c_void,
498+
st_size,
499+
&mut crc32,
500+
)
501+
};
502+
503+
if r.is_error() {
504+
Err(io::Error::from_raw_os_error(r.as_usize()))
505+
} else {
506+
self.st.hdr.crc32 = crc32;
507+
Ok(())
508+
}
509+
}
479510
}
480511

481512
impl Drop for Command {
@@ -501,13 +532,12 @@ mod uefi_command_internal {
501532
set_cursor_position: simple_text_output::ProtocolSetCursorPosition,
502533
enable_cursor: simple_text_output::ProtocolEnableCursor,
503534
mode: *mut simple_text_output::Mode,
504-
_mode: Box<simple_text_output::Mode>,
505535
_buffer: Vec<u16>,
506536
}
507537

508538
impl PipeProtocol {
509539
pub fn new() -> Self {
510-
let mut mode = Box::new(simple_text_output::Mode {
540+
let mode = Box::new(simple_text_output::Mode {
511541
max_mode: 0,
512542
mode: 0,
513543
attribute: 0,
@@ -525,14 +555,13 @@ mod uefi_command_internal {
525555
clear_screen: Self::clear_screen,
526556
set_cursor_position: Self::set_cursor_position,
527557
enable_cursor: Self::enable_cursor,
528-
mode: mode.as_mut(),
529-
_mode: mode,
558+
mode: Box::into_raw(mode),
530559
_buffer: Vec::new(),
531560
}
532561
}
533562

534563
pub fn null() -> Self {
535-
let mut mode = Box::new(simple_text_output::Mode {
564+
let mode = Box::new(simple_text_output::Mode {
536565
max_mode: 0,
537566
mode: 0,
538567
attribute: 0,
@@ -550,8 +579,7 @@ mod uefi_command_internal {
550579
clear_screen: Self::clear_screen,
551580
set_cursor_position: Self::set_cursor_position,
552581
enable_cursor: Self::enable_cursor,
553-
mode: mode.as_mut(),
554-
_mode: mode,
582+
mode: Box::into_raw(mode),
555583
_buffer: Vec::new(),
556584
}
557585
}
@@ -660,4 +688,12 @@ mod uefi_command_internal {
660688
r_efi::efi::Status::UNSUPPORTED
661689
}
662690
}
691+
692+
impl Drop for PipeProtocol {
693+
fn drop(&mut self) {
694+
unsafe {
695+
let _ = Box::from_raw(self.mode);
696+
}
697+
}
698+
}
663699
}

0 commit comments

Comments
 (0)