uefi: process: Fixes from PR · patricklam/verify-rust-std@8d5cf50

@@ -21,6 +21,12 @@ use crate::slice;

2121

use crate::sync::atomic::{AtomicPtr, Ordering};

2222

use crate::sys_common::wstr::WStrUnits;

232324+

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+2430

const BOOT_SERVICES_UNAVAILABLE: io::Error =

2531

const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");

2632

@@ -231,6 +237,13 @@ impl DevicePath {

231237

protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,

232238

) -> io::Result<DevicePath> {

233239

let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>();

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+234247

let path =

235248

unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };

236249

@@ -267,17 +280,9 @@ impl DevicePath {

267280

"DevicePathFromText Protocol not found"

268281

))

269282

}

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-

}

277283278-

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()

281286

}

282287

}

283288

@@ -292,74 +297,122 @@ impl Drop for DevicePath {

292297

}

293298

}

294299295-

pub(crate) struct Protocol<T> {

300+

pub(crate) struct OwnedProtocol<T> {

296301

guid: r_efi::efi::Guid,

297302

handle: NonNull<crate::ffi::c_void>,

298-

protocol: Box<T>,

303+

protocol: *mut T,

299304

}

300305301-

impl<T> Protocol<T> {

302-

const fn new(

303-

guid: r_efi::efi::Guid,

304-

handle: NonNull<crate::ffi::c_void>,

305-

protocol: Box<T>,

306-

) -> Self {

307-

Self { guid, handle, protocol }

308-

}

309-310-

pub(crate) fn create(protocol: T, mut guid: r_efi::efi::Guid) -> io::Result<Self> {

311-

let boot_services: NonNull<r_efi::efi::BootServices> =

306+

impl<T> OwnedProtocol<T> {

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<Self> {

309+

let bt: NonNull<r_efi::efi::BootServices> =

312310

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));

314312

let mut handle: r_efi::efi::Handle = crate::ptr::null_mut();

315313314+

// 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+316318

let r = unsafe {

317-

((*boot_services.as_ptr()).install_protocol_interface)(

319+

func(

318320

&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,

322324

)

323325

};

324326325327

if r.is_error() {

328+

drop(unsafe { Box::from_raw(protocol) });

326329

return Err(crate::io::Error::from_raw_os_error(r.as_usize()));

327330

};

328331329332

let handle = NonNull::new(handle)

330333

.ok_or(io::const_io_error!(io::ErrorKind::Uncategorized, "found null handle"))?;

331334332-

Ok(Self::new(guid, handle, protocol))

335+

Ok(Self { guid, handle, protocol })

333336

}

334337335338

pub(crate) fn handle(&self) -> NonNull<crate::ffi::c_void> {

336339

self.handle

337340

}

338341

}

339342340-

impl<T> Drop for Protocol<T> {

343+

impl<T> Drop for OwnedProtocol<T> {

341344

fn drop(&mut self) {

345+

// Do not deallocate a runtime protocol

342346

if let Some(bt) = boot_services() {

343347

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(

346354

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,

349358

)

350359

};

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+

}

351365

}

352366

}

353367

}

354368355-

impl<T> AsRef<T> for Protocol<T> {

369+

impl<T> AsRef<T> for OwnedProtocol<T> {

356370

fn as_ref(&self) -> &T {

357-

&self.protocol

371+

unsafe { self.protocol.as_ref().unwrap() }

372+

}

373+

}

374+375+

pub(crate) struct OwnedTable<T> {

376+

layout: crate::alloc::Layout,

377+

ptr: *mut T,

378+

}

379+380+

impl<T> OwnedTable<T> {

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

358394

}

359395

}

360396361-

impl<T> AsMut<T> for Protocol<T> {

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<T> Drop for OwnedTable<T> {

415+

fn drop(&mut self) {

416+

unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) };

364417

}

365418

}