Skip to content

Commit

Permalink
linux-bootloader: simplify get_loader_features
Browse files Browse the repository at this point in the history
Rather than calling get_variable_size, allocating a vec, and then
reading into it, use a fixed-size buffer. The behavior is unchanged,
just a little simpler.

Also added a summary of the error behavior to the docstring.
  • Loading branch information
nicholasbishop committed Oct 5, 2024
1 parent e2365a1 commit 0104987
Showing 1 changed file with 26 additions and 17 deletions.
43 changes: 26 additions & 17 deletions rust/uefi/linux-bootloader/src/efivars.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::{format, string::ToString, vec, vec::Vec};
use alloc::{format, string::ToString, vec::Vec};
use core::mem::size_of;
use uefi::{
cstr16, guid,
prelude::{BootServices, RuntimeServices},
Expand Down Expand Up @@ -67,26 +68,34 @@ bitflags! {

/// Get the currently supported EFI features from the loader if they do exist
/// https://systemd.io/BOOT_LOADER_INTERFACE/
///
/// If the variable cannot be read, `EfiLoaderFeatures::default` is returned.
/// If the variable data is the wrong size, `BAD_BUFFER_SIZE` is returned.
/// If the variable data contains unknown flags, `INCOMPATIBLE_VERSION` is returned.
pub fn get_loader_features(runtime_services: &RuntimeServices) -> Result<EfiLoaderFeatures> {
if let Ok(size) =
runtime_services.get_variable_size(cstr16!("LoaderFeatures"), &BOOT_LOADER_VENDOR_UUID)
{
let mut buffer = vec![0; size].into_boxed_slice();
runtime_services.get_variable(
cstr16!("LoaderFeatures"),
&BOOT_LOADER_VENDOR_UUID,
&mut buffer,
)?;
let mut buffer = [0u8; size_of::<EfiLoaderFeatures>()];

return EfiLoaderFeatures::from_bits(u64::from_le_bytes(
(*buffer)
.try_into()
.map_err(|_err| uefi::Status::BAD_BUFFER_SIZE)?,
))
.ok_or_else(|| uefi::Status::INCOMPATIBLE_VERSION.into());
match runtime_services.get_variable(
cstr16!("LoaderFeatures"),
&BOOT_LOADER_VENDOR_UUID,
&mut buffer,
) {
Ok((data, _)) => {
if data.len() != buffer.len() {
return Err(uefi::Status::BAD_BUFFER_SIZE.into());
}
}
Err(err) => {
if err.status() == uefi::Status::BUFFER_TOO_SMALL {
return Err(uefi::Status::BAD_BUFFER_SIZE.into());
} else {
return Ok(EfiLoaderFeatures::default());
}
}
}

Ok(Default::default())
EfiLoaderFeatures::from_bits(u64::from_le_bytes(buffer))
.ok_or_else(|| uefi::Status::INCOMPATIBLE_VERSION.into())
}

bitflags! {
Expand Down

0 comments on commit 0104987

Please # to comment.