Skip to content

Commit c04e423

Browse files
committedMay 22, 2024·
uefi: Make exit_boot_services unsafe
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.
1 parent ec956eb commit c04e423

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed
 

‎uefi-test-runner/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ fn shutdown(mut st: SystemTable<Boot>) -> ! {
199199
info!("Testing complete, exiting boot services...");
200200

201201
// Exit boot services as a proof that it works :)
202-
let (st, mmap) = st.exit_boot_services(MemoryType::LOADER_DATA);
202+
let (st, mmap) = unsafe { st.exit_boot_services(MemoryType::LOADER_DATA) };
203203

204204
info!("Memory Map:");
205205
for desc in mmap.entries() {

‎uefi/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
This provides an initial API for global tables that do not require passing
1313
around a reference.
1414

15+
## Changed
16+
- `SystemTable::exit_boot_services` is now `unsafe`. See that method's
17+
documentation for details of obligations for callers.
18+
1519
## Removed
1620
- Removed the `panic-on-logger-errors` feature of the `uefi` crate. Logger
1721
errors are now silently ignored.

‎uefi/src/table/system.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,27 @@ impl SystemTable<Boot> {
208208
///
209209
/// Note that once the boot services are exited, associated loggers and
210210
/// allocators can't use the boot services anymore. For the corresponding
211-
/// abstractions provided by this crate, invoking this function will
212-
/// automatically disable them.
211+
/// abstractions provided by this crate (see the [`helpers`] module),
212+
/// invoking this function will automatically disable them. If the
213+
/// `global_allocator` feature is enabled, attempting to use the allocator
214+
/// after exiting boot services will panic.
215+
///
216+
/// # Safety
217+
///
218+
/// The caller is responsible for ensuring that no references to
219+
/// boot-services data remain. A non-exhaustive list of resources to check:
220+
///
221+
/// * All protocols will be invalid after exiting boot services. This
222+
/// includes the [`Output`] protocols attached to stdout/stderr. The
223+
/// caller must ensure that no protocol references remain.
224+
/// * The pool allocator is not usable after exiting boot services. Types
225+
/// such as [`PoolString`] which call [`BootServices::free_pool`] on drop
226+
/// must be cleaned up before calling `exit_boot_services`, or leaked to
227+
/// avoid drop ever being called.
228+
/// * All data in the memory map marked as
229+
/// [`MemoryType::BOOT_SERVICES_CODE`] and
230+
/// [`MemoryType::BOOT_SERVICES_DATA`] will become free memory, the caller
231+
/// must ensure that no references to such memory exist.
213232
///
214233
/// # Errors
215234
///
@@ -220,8 +239,12 @@ impl SystemTable<Boot> {
220239
/// All errors are treated as unrecoverable because the system is
221240
/// now in an undefined state. Rather than returning control to the
222241
/// caller, the system will be reset.
242+
///
243+
/// [`helpers`]: crate::helpers
244+
/// [`Output`]: crate::proto::console::text::Output
245+
/// [`PoolString`]: crate::proto::device_path::text::PoolString
223246
#[must_use]
224-
pub fn exit_boot_services(
247+
pub unsafe fn exit_boot_services(
225248
self,
226249
memory_type: MemoryType,
227250
) -> (SystemTable<Runtime>, MemoryMap<'static>) {

0 commit comments

Comments
 (0)
Please sign in to comment.