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

`}

`