Skip to content

Commit 02616ac

Browse files
josephlrGabrielMajeri
authored andcommitted
Properly handle allocation failure
The change in #89 did not properly handle allocation failures. On failure, alloc() returns a null pointer, and this is not checked. This change moves buffer allocation to the new Alloc API, correctly handles allocation failure, and avoids potential unsafety with zero-sized alloc requests. I also removed the dependancy on uefi-services from uefi-alloc. The dependancy isn't needed, and now users can use uefi-exts with their own allocators.
1 parent 954a359 commit 02616ac

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

uefi-exts/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ edition = "2018"
77

88
[dependencies]
99
uefi = { path = ".." }
10-
uefi-services = { path = "../uefi-services" }

uefi-exts/src/file.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use alloc::{alloc::alloc, boxed::Box};
2-
use core::{alloc::Layout, mem, slice};
1+
use super::allocate_buffer;
2+
use alloc::{alloc::Layout, boxed::Box};
3+
use core::mem;
34
use uefi::prelude::*;
45
use uefi::proto::media::file::{File, FileProtocolInfo};
56
use uefi::Result;
@@ -19,15 +20,14 @@ pub trait FileExt: File {
1920
(_, Some(size)) => size,
2021
};
2122

22-
// These unsafe alloc APIs make sure our buffer is correctly aligned. We
23-
// round up a size must always be a multiple of alignment. We turn the
24-
// pointer into a Box<[u8]>, so it's always freed on error.
23+
// We add trailing padding because the size of a rust structure must
24+
// always be a multiple of alignment.
2525
let layout = Layout::from_size_align(size, Info::alignment())
2626
.unwrap()
2727
.pad_to_align()
2828
.unwrap();
29-
let buffer_start = unsafe { alloc(layout) };
30-
let mut buffer = unsafe { Box::from_raw(slice::from_raw_parts_mut(buffer_start, size)) };
29+
let mut buffer = allocate_buffer(layout);
30+
let buffer_start = buffer.as_ptr();
3131

3232
let info = self
3333
.get_info(&mut buffer)

uefi-exts/src/lib.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! which add utility functions to various UEFI objects.
55
66
#![no_std]
7-
#![feature(alloc, alloc_layout_extra)]
7+
#![feature(alloc, alloc_layout_extra, allocator_api)]
88

99
extern crate alloc;
1010

@@ -13,3 +13,24 @@ mod file;
1313

1414
pub use self::boot::BootServicesExt;
1515
pub use self::file::FileExt;
16+
17+
use alloc::{
18+
alloc::{handle_alloc_error, Alloc, Global, Layout},
19+
boxed::Box,
20+
};
21+
use core::slice;
22+
23+
/// Creates a boxed byte buffer using the standard allocator
24+
/// # Panics
25+
/// Calls handle_alloc_error if the layout has a size of zero or allocation fails.
26+
pub fn allocate_buffer(layout: Layout) -> Box<[u8]> {
27+
if layout.size() == 0 {
28+
handle_alloc_error(layout);
29+
}
30+
unsafe {
31+
match Global.alloc(layout) {
32+
Ok(mem) => Box::from_raw(slice::from_raw_parts_mut(mem.as_ptr(), layout.size())),
33+
Err(_) => handle_alloc_error(layout),
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)