Skip to content

Commit e7d275c

Browse files
committed
Check if the DevicePath is valid
1 parent 733855d commit e7d275c

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

src/proto/loaded_image.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
data_types::FromSliceWithNulError,
55
proto::{device_path::DevicePath, Protocol},
66
table::boot::MemoryType,
7-
unsafe_guid, CStr16, Char16, Handle, Status,
7+
unsafe_guid, CStr16, Handle, Status,
88
};
99
use core::{ffi::c_void, mem, slice};
1010

@@ -55,21 +55,18 @@ impl LoadedImage {
5555
self.device_handle
5656
}
5757

58-
/// Return a NULL-terminated Path string including directory and file names.
58+
/// Get a reference to the `file_path`.
5959
///
60-
/// `file_path` is a pointer to the file path portion specific to DeviceHandle
61-
/// that the EFI Image was loaded from. It will be empty if the image is loaded
62-
/// from a buffer and the `file_path` is `None`.
60+
/// Return `None` if the pointer to the file path portion specific to
61+
/// DeviceHandle that the EFI Image was loaded from is null.
6362
///
64-
/// # Safety
63+
/// To get the path name from the `file_path`, the following should be
64+
/// checked to find out if the `DevicePath` is valid:
6565
///
66-
/// The callers should guarantee the image is loaded from file. If the image
67-
/// is loaded from a buffer, make sure not passing an incorrect `DevicePath`,
68-
/// which may case an undefined behavior.
69-
pub unsafe fn file_path(&self) -> &CStr16 {
70-
// path name follows the DevicePathHeader.
71-
let path_name = self.file_path.offset(1);
72-
CStr16::from_ptr(path_name.cast::<Char16>())
66+
/// - The DeviceType should be `MEDIA (0x04)`
67+
/// - The DeviceSubType should be `MEDIA_FILE_PATH (0x04)`
68+
pub fn file_path(&self) -> Option<&DevicePath> {
69+
unsafe { self.file_path.as_ref() }
7370
}
7471

7572
/// Get the load options of the image as a [`&CStr16`].

src/table/boot.rs

+43-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ use super::Header;
44
use crate::data_types::Align;
55
use crate::proto::{device_path::DevicePath, Protocol};
66
#[cfg(feature = "exts")]
7-
use crate::proto::{loaded_image::LoadedImage, media::fs::SimpleFileSystem};
7+
use crate::{
8+
proto::{
9+
device_path::{DeviceSubType, DeviceType},
10+
loaded_image::LoadedImage,
11+
media::fs::SimpleFileSystem,
12+
},
13+
CStr16,
14+
};
815
use crate::{Char16, Event, Guid, Handle, Result, Status};
916
#[cfg(feature = "exts")]
1017
use alloc_api::vec::Vec;
@@ -993,6 +1000,41 @@ impl BootServices {
9931000
OpenProtocolAttributes::Exclusive,
9941001
)
9951002
}
1003+
1004+
/// Get a NULL-terminated Path string the given image was loaded from.
1005+
///
1006+
/// Note the path string will be empty if the image was loaded from a
1007+
/// buffer instead of a path, and the path wasn't set.
1008+
pub fn get_image_file_path(&self, image_handle: Handle) -> Result<&CStr16> {
1009+
let loaded_image = self.open_protocol::<LoadedImage>(
1010+
OpenProtocolParams {
1011+
handle: image_handle,
1012+
agent: image_handle,
1013+
controller: None,
1014+
},
1015+
OpenProtocolAttributes::Exclusive,
1016+
)?;
1017+
let loaded_image = unsafe { &*loaded_image.interface.get() };
1018+
1019+
// If the file_path is None, it means the operation isn't supported.
1020+
let file_path = loaded_image.file_path().ok_or(Status::UNSUPPORTED)?;
1021+
1022+
// check if the type of `file_path` is correct
1023+
if let (DeviceType::MEDIA, DeviceSubType::MEDIA_FILE_PATH) =
1024+
(file_path.device_type(), file_path.sub_type())
1025+
{
1026+
let file_path = file_path as *const DevicePath;
1027+
1028+
unsafe {
1029+
// path name follows by the `DevicePathHeader`
1030+
let path_name = file_path.offset(1).cast();
1031+
Ok(CStr16::from_ptr(path_name))
1032+
}
1033+
} else {
1034+
// incorrect type, return `UNSUPPORTED`
1035+
Err(Status::UNSUPPORTED.into())
1036+
}
1037+
}
9961038
}
9971039

9981040
impl super::Table for BootServices {

0 commit comments

Comments
 (0)