fix(utils): improve safety of media loader and utf-16 handling

This commit is contained in:
2025-11-01 18:49:10 -04:00
parent 992520c201
commit a998832f6b
2 changed files with 11 additions and 16 deletions

View File

@@ -280,11 +280,14 @@ pub fn utf16_bytes_to_cstring16(bytes: &[u8]) -> Result<CString16> {
bail!("utf16 bytes must be a multiple of 2"); bail!("utf16 bytes must be a multiple of 2");
} }
// SAFETY: reinterpret &[u8] as &[u16]. // Convert the bytes to UTF-16 data.
// We just validated it has the right length. let data = bytes
let ptr = bytes.as_ptr() as *const u16; // Chunk everything into two bytes.
let len = bytes.len() / 2; .chunks_exact(2)
let utf16 = unsafe { std::slice::from_raw_parts(ptr, len) }; // Reinterpret the bytes as u16 little-endian.
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
// Collect the result into a vector.
.collect::<Vec<_>>();
CString16::try_from(utf16.to_vec()).context("unable to convert utf16 bytes to CString16") CString16::try_from(data).context("unable to convert utf16 bytes to CString16")
} }

View File

@@ -33,8 +33,6 @@ struct MediaLoaderProtocol {
/// You MUST call [MediaLoaderHandle::unregister] when ready to unregister. /// You MUST call [MediaLoaderHandle::unregister] when ready to unregister.
/// [Drop] is not implemented for this type. /// [Drop] is not implemented for this type.
pub struct MediaLoaderHandle { pub struct MediaLoaderHandle {
/// The vendor GUID of the media loader.
guid: Guid,
/// The handle of the media loader in the UEFI stack. /// The handle of the media loader in the UEFI stack.
handle: Handle, handle: Handle,
/// The protocol interface pointer. /// The protocol interface pointer.
@@ -229,7 +227,6 @@ impl MediaLoaderHandle {
// Return a handle to the media loader. // Return a handle to the media loader.
Ok(Self { Ok(Self {
guid,
handle: primary_handle, handle: primary_handle,
protocol, protocol,
path, path,
@@ -239,13 +236,8 @@ impl MediaLoaderHandle {
/// Unregisters a media loader from the UEFI stack. /// Unregisters a media loader from the UEFI stack.
/// This will free the memory allocated by the passed data. /// This will free the memory allocated by the passed data.
pub fn unregister(self) -> Result<()> { pub fn unregister(self) -> Result<()> {
// Check if the media loader is registered. // SAFETY: We know that the media loader is registered if the handle is valid,
// If it is not, we don't need to do anything. // so we can safely uninstall it.
if !Self::already_registered(self.guid)? {
return Ok(());
}
// SAFETY: We know that the media loader is registered, so we can safely uninstall it.
// We should have allocated the pointers involved, so we can safely free them. // We should have allocated the pointers involved, so we can safely free them.
unsafe { unsafe {
// Uninstall the protocol interface for the device path protocol. // Uninstall the protocol interface for the device path protocol.