Skip to content

Commit

Permalink
uefi: Make exit_boot_services unsafe
Browse files Browse the repository at this point in the history
This method was already unsafe in practice, since it's very hard to statically
ensure that no references to boot-services data exist. Change the signature to
acknowledge that reality, and update the docstring with details.
  • Loading branch information
nicholasbishop committed May 2, 2024
1 parent b325e72 commit 4ae0cd6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion uefi-test-runner/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ fn shutdown(mut st: SystemTable<Boot>) -> ! {
info!("Testing complete, shutting down...");

// Exit boot services as a proof that it works :)
let (st, _iter) = st.exit_boot_services(MemoryType::LOADER_DATA);
let (st, _iter) = unsafe { st.exit_boot_services(MemoryType::LOADER_DATA) };

#[cfg(target_arch = "x86_64")]
{
Expand Down
4 changes: 4 additions & 0 deletions uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
This provides an initial API for global tables that do not require passing
around a reference.

## Changed
- `SystemTable::exit_boot_services` is now `unsafe`. See that method's
documentation for details of obligations for callers.

## Removed
- Removed the `panic-on-logger-errors` feature of the `uefi` crate. Logger
errors are now silently ignored.
Expand Down
19 changes: 18 additions & 1 deletion uefi/src/table/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,23 @@ impl SystemTable<Boot> {
/// abstractions provided by this crate, invoking this function will
/// automatically disable them.
///
/// # Safety
///
/// The caller is responsible for ensuring that no references to
/// boot-services data remain. A non-exhaustive list of resources to check:
///
/// * All protocols will be invalid after exiting boot services. This
/// includes the [`Output`] protocols attached to stdout/stderr. The
/// caller must ensure that no protocol references remain.
/// * The pool allocator is not usable after exiting boot services. Types
/// such as [`PoolString`] which call [`BootServices::free_pool`] on drop
/// must be cleaned up before calling `exit_boot_services`, or leaked to
/// avoid drop ever being called.
/// * All data in the memory map marked as
/// [`MemoryType::BOOT_SERVICES_CODE`] and
/// [`MemoryType::BOOT_SERVICES_DATA`] will become free memory, the caller
/// must ensure that no references to such memory exist.
///
/// # Errors
///
/// This function will fail if it is unable to allocate memory for
Expand All @@ -221,7 +238,7 @@ impl SystemTable<Boot> {
/// now in an undefined state. Rather than returning control to the
/// caller, the system will be reset.
#[must_use]
pub fn exit_boot_services(
pub unsafe fn exit_boot_services(
self,
memory_type: MemoryType,
) -> (SystemTable<Runtime>, MemoryMap<'static>) {
Expand Down

0 comments on commit 4ae0cd6

Please sign in to comment.