uefi: process: Fixes from PR · model-checking/verify-rust-std@8d5cf50 (original) (raw)
`@@ -21,6 +21,12 @@ use crate::slice;
`
21
21
`use crate::sync::atomic::{AtomicPtr, Ordering};
`
22
22
`use crate::sys_common::wstr::WStrUnits;
`
23
23
``
``
24
`+
type BootInstallMultipleProtocolInterfaces =
`
``
25
`+
unsafe extern "efiapi" fn(_: *mut r_efi::efi::Handle, _: ...) -> r_efi::efi::Status;
`
``
26
+
``
27
`+
type BootUninstallMultipleProtocolInterfaces =
`
``
28
`+
unsafe extern "efiapi" fn(_: r_efi::efi::Handle, _: ...) -> r_efi::efi::Status;
`
``
29
+
24
30
`const BOOT_SERVICES_UNAVAILABLE: io::Error =
`
25
31
`const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
`
26
32
``
`@@ -231,6 +237,13 @@ impl DevicePath {
`
231
237
`protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,
`
232
238
`) -> io::Result {
`
233
239
`let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec>();
`
``
240
`+
if path_vec[..path_vec.len() - 1].contains(&0) {
`
``
241
`+
return Err(const_io_error!(
`
``
242
`+
io::ErrorKind::InvalidInput,
`
``
243
`+
"strings passed to UEFI cannot contain NULs",
`
``
244
`+
));
`
``
245
`+
}
`
``
246
+
234
247
`let path =
`
235
248
`unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };
`
236
249
``
`@@ -267,17 +280,9 @@ impl DevicePath {
`
267
280
`"DevicePathFromText Protocol not found"
`
268
281
`))
`
269
282
`}
`
270
``
`-
}
`
271
``
-
272
``
`-
impl AsRef<r_efi::protocols::device_path::Protocol> for DevicePath {
`
273
``
`-
fn as_ref(&self) -> &r_efi::protocols::device_path::Protocol {
`
274
``
`-
unsafe { self.0.as_ref() }
`
275
``
`-
}
`
276
``
`-
}
`
277
283
``
278
``
`-
impl AsMut<r_efi::protocols::device_path::Protocol> for DevicePath {
`
279
``
`-
fn as_mut(&mut self) -> &mut r_efi::protocols::device_path::Protocol {
`
280
``
`-
unsafe { self.0.as_mut() }
`
``
284
`+
pub(crate) fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
`
``
285
`+
self.0.as_ptr()
`
281
286
`}
`
282
287
`}
`
283
288
``
`@@ -292,74 +297,122 @@ impl Drop for DevicePath {
`
292
297
`}
`
293
298
`}
`
294
299
``
295
``
`-
pub(crate) struct Protocol {
`
``
300
`+
pub(crate) struct OwnedProtocol {
`
296
301
`guid: r_efi::efi::Guid,
`
297
302
`handle: NonNullcrate::ffi::c_void,
`
298
``
`-
protocol: Box,
`
``
303
`+
protocol: *mut T,
`
299
304
`}
`
300
305
``
301
``
`-
impl Protocol {
`
302
``
`-
const fn new(
`
303
``
`-
guid: r_efi::efi::Guid,
`
304
``
`-
handle: NonNullcrate::ffi::c_void,
`
305
``
`-
protocol: Box,
`
306
``
`-
) -> Self {
`
307
``
`-
Self { guid, handle, protocol }
`
308
``
`-
}
`
309
``
-
310
``
`-
pub(crate) fn create(protocol: T, mut guid: r_efi::efi::Guid) -> io::Result {
`
311
``
`-
let boot_services: NonNull<r_efi::efi::BootServices> =
`
``
306
`+
impl OwnedProtocol {
`
``
307
`+
// FIXME: Consider using unsafe trait for matching protocol with guid
`
``
308
`+
pub(crate) unsafe fn create(protocol: T, mut guid: r_efi::efi::Guid) -> io::Result {
`
``
309
`+
let bt: NonNull<r_efi::efi::BootServices> =
`
312
310
`boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
`
313
``
`-
let mut protocol = Box::new(protocol);
`
``
311
`+
let protocol: *mut T = Box::into_raw(Box::new(protocol));
`
314
312
`let mut handle: r_efi::efi::Handle = crate::ptr::null_mut();
`
315
313
``
``
314
`+
// FIXME: Move into r-efi once extended_varargs_abi_support is stablized
`
``
315
`+
let func: BootInstallMultipleProtocolInterfaces =
`
``
316
`+
unsafe { crate::mem::transmute((*bt.as_ptr()).install_multiple_protocol_interfaces) };
`
``
317
+
316
318
`let r = unsafe {
`
317
``
`-
((*boot_services.as_ptr()).install_protocol_interface)(
`
``
319
`+
func(
`
318
320
`&mut handle,
`
319
``
`-
&mut guid,
`
320
``
`-
r_efi::efi::NATIVE_INTERFACE,
`
321
``
`-
protocol.as_mut() as *mut T as *mut crate::ffi::c_void,
`
``
321
`+
&mut guid as *mut _ as *mut crate::ffi::c_void,
`
``
322
`+
protocol as *mut crate::ffi::c_void,
`
``
323
`+
crate::ptr::null_mut() as *mut crate::ffi::c_void,
`
322
324
`)
`
323
325
`};
`
324
326
``
325
327
`if r.is_error() {
`
``
328
`+
drop(unsafe { Box::from_raw(protocol) });
`
326
329
`return Err(crate::io::Error::from_raw_os_error(r.as_usize()));
`
327
330
`};
`
328
331
``
329
332
`let handle = NonNull::new(handle)
`
330
333
`.ok_or(io::const_io_error!(io::ErrorKind::Uncategorized, "found null handle"))?;
`
331
334
``
332
``
`-
Ok(Self::new(guid, handle, protocol))
`
``
335
`+
Ok(Self { guid, handle, protocol })
`
333
336
`}
`
334
337
``
335
338
`pub(crate) fn handle(&self) -> NonNullcrate::ffi::c_void {
`
336
339
`self.handle
`
337
340
`}
`
338
341
`}
`
339
342
``
340
``
`-
impl Drop for Protocol {
`
``
343
`+
impl Drop for OwnedProtocol {
`
341
344
`fn drop(&mut self) {
`
``
345
`+
// Do not deallocate a runtime protocol
`
342
346
`if let Some(bt) = boot_services() {
`
343
347
`let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
`
344
``
`-
unsafe {
`
345
``
`-
((*bt.as_ptr()).uninstall_protocol_interface)(
`
``
348
`+
// FIXME: Move into r-efi once extended_varargs_abi_support is stablized
`
``
349
`+
let func: BootUninstallMultipleProtocolInterfaces = unsafe {
`
``
350
`+
crate::mem::transmute((*bt.as_ptr()).uninstall_multiple_protocol_interfaces)
`
``
351
`+
};
`
``
352
`+
let status = unsafe {
`
``
353
`+
func(
`
346
354
`self.handle.as_ptr(),
`
347
``
`-
&mut self.guid,
`
348
``
`-
self.protocol.as_mut() as *mut T as *mut crate::ffi::c_void,
`
``
355
`+
&mut self.guid as *mut _ as *mut crate::ffi::c_void,
`
``
356
`+
self.protocol as *mut crate::ffi::c_void,
`
``
357
`+
crate::ptr::null_mut() as *mut crate::ffi::c_void,
`
349
358
`)
`
350
359
`};
`
``
360
+
``
361
`+
// Leak the protocol in case uninstall fails
`
``
362
`+
if status == r_efi::efi::Status::SUCCESS {
`
``
363
`+
let _ = unsafe { Box::from_raw(self.protocol) };
`
``
364
`+
}
`
351
365
`}
`
352
366
`}
`
353
367
`}
`
354
368
``
355
``
`-
impl AsRef for Protocol {
`
``
369
`+
impl AsRef for OwnedProtocol {
`
356
370
`fn as_ref(&self) -> &T {
`
357
``
`-
&self.protocol
`
``
371
`+
unsafe { self.protocol.as_ref().unwrap() }
`
``
372
`+
}
`
``
373
`+
}
`
``
374
+
``
375
`+
pub(crate) struct OwnedTable {
`
``
376
`+
layout: crate::alloc::Layout,
`
``
377
`+
ptr: *mut T,
`
``
378
`+
}
`
``
379
+
``
380
`+
impl OwnedTable {
`
``
381
`+
pub(crate) fn from_table_header(hdr: &r_efi::efi::TableHeader) -> Self {
`
``
382
`+
let header_size = hdr.header_size as usize;
`
``
383
`+
let layout = crate::alloc::Layout::from_size_align(header_size, 8).unwrap();
`
``
384
`+
let ptr = unsafe { crate::alloc::alloc(layout) as *mut T };
`
``
385
`+
Self { layout, ptr }
`
``
386
`+
}
`
``
387
+
``
388
`+
pub(crate) const fn as_ptr(&self) -> *const T {
`
``
389
`+
self.ptr
`
``
390
`+
}
`
``
391
+
``
392
`+
pub(crate) const fn as_mut_ptr(&self) -> *mut T {
`
``
393
`+
self.ptr
`
358
394
`}
`
359
395
`}
`
360
396
``
361
``
`-
impl AsMut for Protocol {
`
362
``
`-
fn as_mut(&mut self) -> &mut T {
`
363
``
`-
&mut self.protocol
`
``
397
`+
impl OwnedTable<r_efi::efi::SystemTable> {
`
``
398
`+
pub(crate) fn from_table(tbl: *const r_efi::efi::SystemTable) -> Self {
`
``
399
`+
let hdr = unsafe { (*tbl).hdr };
`
``
400
+
``
401
`+
let owned_tbl = Self::from_table_header(&hdr);
`
``
402
`+
unsafe {
`
``
403
`+
crate::ptr::copy_nonoverlapping(
`
``
404
`+
tbl as *const u8,
`
``
405
`+
owned_tbl.as_mut_ptr() as *mut u8,
`
``
406
`+
hdr.header_size as usize,
`
``
407
`+
)
`
``
408
`+
};
`
``
409
+
``
410
`+
owned_tbl
`
``
411
`+
}
`
``
412
`+
}
`
``
413
+
``
414
`+
impl Drop for OwnedTable {
`
``
415
`+
fn drop(&mut self) {
`
``
416
`+
unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) };
`
364
417
`}
`
365
418
`}
`