Skip to content

Commit 8b7fd50

Browse files
committed
Added missing Safety comments to driver_services.rs in patina_dxe_core.
1 parent 4a2ee56 commit 8b7fd50

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

patina_dxe_core/src/driver_services.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ fn get_platform_driver_override_bindings(
4747
{
4848
Err(_) => return Vec::new(),
4949
Ok(protocol) => unsafe {
50+
// SAFETY: locate_protocol guarantees that if `Ok` is returned, a valid pointer is encapsulated in it.
5051
(protocol as *mut efi::protocols::platform_driver_override::Protocol).as_mut().expect("bad protocol ptr")
5152
},
5253
};
@@ -80,6 +81,7 @@ fn get_family_override_bindings() -> Vec<*mut efi::protocols::driver_binding::Pr
8081
for handle in driver_binding_handles {
8182
match PROTOCOL_DB.get_interface_for_handle(handle, efi::protocols::driver_family_override::PROTOCOL_GUID) {
8283
Ok(protocol) => {
84+
// SAFETY: get_interface_for_handle guarantees that if `Ok` is returned, a valid pointer is encapsulated in it.
8385
let driver_override_protocol = unsafe {
8486
(protocol as *mut efi::protocols::driver_family_override::Protocol)
8587
.as_mut()
@@ -103,6 +105,7 @@ fn get_bus_specific_override_bindings(
103105
.get_interface_for_handle(controller_handle, efi::protocols::bus_specific_driver_override::PROTOCOL_GUID)
104106
{
105107
Err(_) => return Vec::new(),
108+
// SAFETY: get_interface_for_handle guarantees that if `Ok` is returned, a valid pointer is encapsulated in it.
106109
Ok(protocol) => unsafe {
107110
(protocol as *mut efi::protocols::bus_specific_driver_override::Protocol)
108111
.as_mut()
@@ -133,6 +136,9 @@ fn get_all_driver_bindings() -> Vec<*mut efi::protocols::driver_binding::Protoco
133136
Ok(handles) => get_bindings_for_handles(handles),
134137
};
135138

139+
// SAFETY: driver_bindings must contain valid pointers/handles (a & b as well as *a & *b)
140+
// when sort_unstable_by() is called. If .locate_handles() returns 'Ok' and handles is
141+
// not empty, we rely on get_bindings_for_handles to return a valid Vec.
136142
driver_bindings.sort_unstable_by(|a, b| unsafe { (*(*b)).version.cmp(&(*(*a)).version) });
137143

138144
driver_bindings
@@ -162,6 +168,7 @@ fn authenticate_connect(
162168
};
163169

164170
if let Ok(mut file_path) = file_path {
171+
// SAFETY: Pointer is validated using .expect(), will panic if .as_ref() returns a NULL pointer
165172
let security2 = unsafe {
166173
(security2_ptr as *mut patina::pi::protocols::security2::Protocol)
167174
.as_ref()
@@ -222,6 +229,8 @@ fn core_connect_single_controller(
222229
loop {
223230
let mut started_drivers = Vec::new();
224231
for driver_binding_interface in driver_candidates.clone() {
232+
// SAFETY: driver_binding_interface is a clone of driver_candidates which is created above.
233+
// The pointer should be valid as long as driver_candidates is successfully allocated.
225234
let driver_binding = unsafe { &mut *(driver_binding_interface) };
226235
let device_path = remaining_device_path.or(Some(core::ptr::null_mut())).expect("must be some");
227236

@@ -323,7 +332,9 @@ pub unsafe fn core_connect_controller(
323332

324333
if recursive {
325334
for child in PROTOCOL_DB.get_child_handles(handle) {
326-
//ignore the return value to match behavior of edk2 reference.
335+
// ignore the return value to match behavior of edk2 reference.
336+
// SAFETY: We do not remove any of these handles during this call, though it is
337+
// possible for a different entity at another TPL to do so.
327338
_ = unsafe { core_connect_controller(child, Vec::new(), None, true) };
328339
}
329340
}
@@ -491,6 +502,8 @@ pub unsafe fn core_disconnect_controller(
491502
.get_interface_for_handle(driver_handle, efi::protocols::driver_binding::PROTOCOL_GUID)
492503
.or(Err(EfiError::InvalidParameter))?;
493504
let driver_binding_interface = driver_binding_interface as *mut efi::protocols::driver_binding::Protocol;
505+
// SAFETY: driver_binding_interface is validated above, would have been caught with the .or and ? above with
506+
// the loop being terminated.
494507
let driver_binding = unsafe { &mut *(driver_binding_interface) };
495508

496509
let mut status = efi::Status::SUCCESS;
@@ -519,8 +532,17 @@ extern "efiapi" fn disconnect_controller(
519532
driver_image_handle: efi::Handle,
520533
child_handle: efi::Handle,
521534
) -> efi::Status {
535+
if controller_handle.is_null() {
536+
return efi::Status::INVALID_PARAMETER;
537+
}
538+
522539
let driver_image_handle = NonNull::new(driver_image_handle).map(|x| x.as_ptr());
523540
let child_handle = NonNull::new(child_handle).map(|x| x.as_ptr());
541+
// SAFETY: Caller must ensure controller_handle is valid for the duration of the call.
542+
// driver_image_handle and child_handle are both created above using NonNull which should
543+
// guarantee they are non-null pointers. controller_handle is validated above. We do not
544+
// remove any of these handles during this call, though it is possible for a different
545+
// entity at another TPL to do so.
524546
unsafe {
525547
match core_disconnect_controller(controller_handle, driver_image_handle, child_handle) {
526548
Err(err) => err.into(),
@@ -554,6 +576,8 @@ mod tests {
554576
fn with_locked_state<F: Fn() + std::panic::RefUnwindSafe>(f: F) {
555577
test_support::with_global_lock(|| {
556578
test_support::init_test_logger();
579+
// SAFETY: init_test_protocol_db modifies global state. It is being called within a
580+
// lock to have exclusive mutable access to the protocol database.
557581
unsafe {
558582
test_support::init_test_protocol_db();
559583
}
@@ -761,6 +785,8 @@ mod tests {
761785
assert_eq!(bindings.len(), 2);
762786

763787
// Verify the binding versions
788+
// SAFETY: The length of bindings is being verified above. This should guarantee
789+
// bindings contains at least two valid elements which are checked below.
764790
unsafe {
765791
assert_eq!((*bindings[0]).version, 10);
766792
assert_eq!((*bindings[1]).version, 20);
@@ -972,6 +998,8 @@ mod tests {
972998

973999
// First binding should be from handle2 (version 200)
9741000
// Second binding should be from handle1 (version 100)
1001+
// SAFETY: The length of bindings is being verified above. This should guarantee
1002+
// bindings contains at least two valid elements which are checked below.
9751003
unsafe {
9761004
assert_eq!((*bindings[0]).version, 20); // handle2's binding version
9771005
assert_eq!((*bindings[1]).version, 10); // handle1's binding version
@@ -1019,6 +1047,8 @@ mod tests {
10191047
assert_eq!(bindings.len(), 3);
10201048

10211049
// Verify the correct order by version (descending)
1050+
// SAFETY: The length of bindings is being verified above. This should guarantee
1051+
// bindings contains at least three valid elements which are checked below.
10221052
unsafe {
10231053
assert_eq!((*bindings[0]).version, 30); // handle2's binding - highest version
10241054
assert_eq!((*bindings[1]).version, 20); // handle3's binding - middle version
@@ -1225,6 +1255,9 @@ mod tests {
12251255
START_CALL_COUNT.store(0, Ordering::SeqCst);
12261256

12271257
// Test 1: Basic connection (non-recursive)
1258+
// SAFETY: Both controller_handle and driver_handle are required to be valid. Both are
1259+
// set via an .unwrap() call from an .install_protocol_interface() call. These calls
1260+
// would panic if an error was returned.
12281261
unsafe {
12291262
let result = core_connect_controller(
12301263
controller_handle,
@@ -1263,6 +1296,9 @@ mod tests {
12631296
.unwrap();
12641297

12651298
// Test recursive connection
1299+
// SAFETY: Both controller_handle and driver_handle are required to be valid. Both are
1300+
// set via an .unwrap() call from an .install_protocol_interface() call. These calls
1301+
// would panic if an error was returned.
12661302
unsafe {
12671303
let result = core_connect_controller(
12681304
controller_handle,
@@ -1285,6 +1321,10 @@ mod tests {
12851321
SUPPORTED_CALL_COUNT.store(0, Ordering::SeqCst);
12861322
START_CALL_COUNT.store(0, Ordering::SeqCst);
12871323

1324+
// SAFETY: controller_handle, driver_handle and end_path_ptr are required to be valid.
1325+
// controller_handle and driver_handle are set via an .unwrap() call from an
1326+
// .install_protocol_interface() call. These calls would panic if an error was returned.
1327+
// end_path_ptr was set via Box::into_raw which is guaranteed to return a non-null pointer.
12881328
unsafe {
12891329
let result = core_connect_controller(
12901330
controller_handle,
@@ -1432,6 +1472,8 @@ mod tests {
14321472
.unwrap();
14331473

14341474
// Test disconnect without specifying driver or child
1475+
// SAFETY: controller_handle is required to be valid. It was set via an .unwrap() call
1476+
// from an .install_protocol_interface() call. This call would panic if an error was returned.
14351477
unsafe {
14361478
let result = core_disconnect_controller(controller_handle, None, None);
14371479
assert!(result.is_ok(), "Should successfully disconnect all drivers");
@@ -1538,6 +1580,8 @@ mod tests {
15381580
LAST_CHILD_COUNT.store(999, Ordering::SeqCst); // Set to invalid value to detect changes
15391581

15401582
// Test disconnect - should call stop function
1583+
// SAFETY: controller_handle is required to be valid. It was set via an .unwrap() call
1584+
// from an .install_protocol_interface() call. This call would panic if an error was returned.
15411585
unsafe {
15421586
let result = core_disconnect_controller(controller_handle, None, None);
15431587
assert!(result.is_ok(), "disconnect should succeed");
@@ -1657,6 +1701,9 @@ mod tests {
16571701
// Test disconnect with specific child handle (which is the ONLY child)
16581702
// This should trigger: is_only_child = total_children == child_handles.len() = true
16591703
// Because: total_children = 1, child_handles.retain() keeps 1 child, so 1 == 1
1704+
// SAFETY: Both controller_handle and child_handle are required to be valid. Both were set
1705+
// via an .unwrap() call from an .install_protocol_interface() call. These calls would panic
1706+
// if an error was returned.
16601707
unsafe {
16611708
let result = core_disconnect_controller(controller_handle, None, Some(child_handle));
16621709
assert!(result.is_ok(), "disconnect should succeed");
@@ -1690,6 +1737,10 @@ mod tests {
16901737
let invalid_driver_handle = 0x9999 as efi::Handle;
16911738

16921739
// Test disconnect with invalid driver handle
1740+
// SAFETY: Both controller_handle and invalid_driver_handle are required to be valid.
1741+
// controller_handle is set via an .unwrap() call from an .install_protocol_interface()
1742+
// call. This call would panic if an error was returned. invalid_driver_handle is
1743+
// statically set to 0x9999 which guarantees it is non-null.
16931744
unsafe {
16941745
let result = core_disconnect_controller(
16951746
controller_handle,
@@ -1726,6 +1777,10 @@ mod tests {
17261777
let invalid_child_handle = 0x8888 as efi::Handle;
17271778

17281779
// Test disconnect with invalid child handle
1780+
// SAFETY: Both controller_handle and invalid_child_handle are required to be valid.
1781+
// controller_handle is set via an .unwrap() call from an .install_protocol_interface()
1782+
// call. This call would panic if an error was returned. invalid_child_handle is
1783+
// statically set to 0x8888 which guarantees it is non-null.
17291784
unsafe {
17301785
let result = core_disconnect_controller(
17311786
controller_handle,

0 commit comments

Comments
 (0)