major cleanup
This commit is contained in:
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -1,12 +1,11 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "barnacle"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"uefi",
|
||||
"uefi-services",
|
||||
]
|
||||
@ -97,9 +96,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ucs2"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad643914094137d475641b6bab89462505316ec2ce70907ad20102d28a79ab8"
|
||||
checksum = "df79298e11f316400c57ec268f3c2c29ac3c4d4777687955cd3d4f3a35ce7eba"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
]
|
||||
@ -132,9 +131,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uefi-raw"
|
||||
version = "0.5.0"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "864ac69eadd877bfb34e7814be1928122ed0057d9f975169a56ee496aa7bdfd7"
|
||||
checksum = "efa8716f52e8cab8bcedfd5052388a0f263b69fe5cc2561548dc6a530678333c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"ptr_meta",
|
||||
@ -154,9 +153,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uguid"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ef516f0806c5f61da6aa95125d0eb2d91cc95b2df426c06bde8be657282aee5"
|
||||
checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@ -1,20 +1,10 @@
|
||||
[package]
|
||||
name = "barnacle"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "barnacle"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[lib]
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.20"
|
||||
uefi = "0.26.0"
|
||||
uefi-services = "0.23.0"
|
||||
|
||||
@ -20,8 +20,8 @@ pub struct Loader {
|
||||
pub fn make_loader(pointer: *const c_void, size: usize) -> Loader {
|
||||
Loader {
|
||||
_handler: initrd_loadfile2 as *const c_void,
|
||||
buf: pointer as *const c_void,
|
||||
size: size as usize,
|
||||
buf: pointer,
|
||||
size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,8 +54,8 @@ pub fn install_initrd(
|
||||
}
|
||||
|
||||
/// Creates a device path for a virtual device with the Linux initrd vendor GUID
|
||||
pub fn make_initrd_device_path<'a>(buf: &'a mut [MaybeUninit<u8>; 256]) -> &'a DevicePath {
|
||||
&build::DevicePathBuilder::with_buf(buf)
|
||||
pub fn make_initrd_device_path(buf: &mut [MaybeUninit<u8>; 256]) -> &DevicePath {
|
||||
build::DevicePathBuilder::with_buf(buf)
|
||||
.push(&build::media::Vendor {
|
||||
vendor_guid: LINUX_INITRD_DEVICE_GUID,
|
||||
vendor_defined_data: &[],
|
||||
@ -77,7 +77,7 @@ fn initrd_loadfile2(
|
||||
) -> Status {
|
||||
unsafe {
|
||||
// Invalid buffer or insufficient size
|
||||
if (*this).size > *size || buf == core::ptr::null_mut() {
|
||||
if (*this).size > *size || buf.is_null() {
|
||||
// Update size parameter to specify expected space
|
||||
*size = (*this).size;
|
||||
return Status::BUFFER_TOO_SMALL;
|
||||
|
||||
@ -11,8 +11,13 @@ mod pe;
|
||||
mod secureboot;
|
||||
mod unicode;
|
||||
|
||||
pub fn bootloader(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
||||
uefi_services::init(&mut system_table).unwrap();
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
pub fn panic(_: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
pub fn bootloader(image_handle: Handle, system_table: SystemTable<Boot>) -> Status {
|
||||
let boot_services = system_table.boot_services();
|
||||
let sections = get_loader_sections(boot_services).unwrap();
|
||||
start_linux(image_handle, boot_services, sections).unwrap();
|
||||
|
||||
26
src/linux.rs
26
src/linux.rs
@ -22,22 +22,22 @@ pub fn start_linux(
|
||||
) -> Result {
|
||||
// Load kernel as image from memory ignoring secure boot
|
||||
// Image is already trusted (signed) by being part of this EFI program
|
||||
let handle = unsafe {
|
||||
run_in_security_override(boot_services, || {
|
||||
boot_services
|
||||
.load_image(
|
||||
image_handle,
|
||||
LoadImageSource::FromBuffer {
|
||||
buffer: &*slice_from_raw_parts::<u8>(
|
||||
let handle = run_in_security_override(boot_services, || {
|
||||
boot_services
|
||||
.load_image(
|
||||
image_handle,
|
||||
LoadImageSource::FromBuffer {
|
||||
buffer: unsafe {
|
||||
&*slice_from_raw_parts::<u8>(
|
||||
sections.linux.pointer,
|
||||
sections.linux.size as usize,
|
||||
),
|
||||
file_path: None,
|
||||
)
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
};
|
||||
file_path: None,
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
})?;
|
||||
|
||||
let mut linux_image = boot_services
|
||||
.open_protocol_exclusive::<LoadedImage>(handle)
|
||||
|
||||
21
src/pe.rs
21
src/pe.rs
@ -2,9 +2,9 @@ use uefi::prelude::BootServices;
|
||||
use uefi::proto::loaded_image::LoadedImage;
|
||||
use uefi::{Error, Result, Status};
|
||||
|
||||
const LINUX_SNAME: [u8; 8] = [0x2e, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0, 0];
|
||||
const CMDLINE_SNAME: [u8; 8] = [0x2e, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65];
|
||||
const INITRD_SNAME: [u8; 8] = [0x2e, 0x69, 0x6e, 0x69, 0x74, 0x72, 0x64, 0];
|
||||
const LINUX_SNAME: [u8; 8] = *b".linux\0\0";
|
||||
const CMDLINE_SNAME: [u8; 8] = *b".cmdline";
|
||||
const INITRD_SNAME: [u8; 8] = *b".initrd\0";
|
||||
|
||||
pub struct PESection {
|
||||
pub name: [u8; 8],
|
||||
@ -52,8 +52,8 @@ pub fn get_loader_sections(boot_services: &BootServices) -> Result<BootSections>
|
||||
|
||||
// Section name at 0 bytes offset, 8 bytes long
|
||||
let mut name = [0; 8];
|
||||
for j in 0..8 {
|
||||
name[j] = *section_row_ptr.add(j);
|
||||
for (j, char) in name.iter_mut().enumerate() {
|
||||
*char = *section_row_ptr.add(j);
|
||||
}
|
||||
|
||||
// Section VMA at 12 bytes offset, 4 bytes long
|
||||
@ -68,12 +68,11 @@ pub fn get_loader_sections(boot_services: &BootServices) -> Result<BootSections>
|
||||
};
|
||||
|
||||
// Section identification
|
||||
if section.name == LINUX_SNAME {
|
||||
tmp_sections.linux = Some(section);
|
||||
} else if section.name == CMDLINE_SNAME {
|
||||
tmp_sections.cmdline = Some(section);
|
||||
} else if section.name == INITRD_SNAME {
|
||||
tmp_sections.initrd = Some(section);
|
||||
match section.name {
|
||||
LINUX_SNAME => tmp_sections.linux = Some(section),
|
||||
CMDLINE_SNAME => tmp_sections.cmdline = Some(section),
|
||||
INITRD_SNAME => tmp_sections.initrd = Some(section),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
use core::ffi::c_void;
|
||||
|
||||
use log::info;
|
||||
use uefi::{prelude::BootServices, proto::unsafe_protocol};
|
||||
use uefi::{prelude::BootServices, proto::unsafe_protocol, Result};
|
||||
|
||||
#[unsafe_protocol("A46423E3-4617-49F1-B9FF-D1BFA9115839")]
|
||||
struct SecurityArch {
|
||||
@ -22,60 +21,50 @@ fn security_handler() -> bool {
|
||||
/// Runs a function with a blind secure boot validator
|
||||
/// Plagiarized from systemd-stub's "hack"
|
||||
/// There must be a better way
|
||||
pub fn run_in_security_override<R, T: Fn() -> R>(boot_services: &BootServices, function: T) -> R {
|
||||
// Backup storage
|
||||
pub fn run_in_security_override<R, T: Fn() -> R>(
|
||||
boot_services: &BootServices,
|
||||
function: T,
|
||||
) -> Result<R> {
|
||||
// Temporary storage for restoration later
|
||||
let mut df_security1 = None;
|
||||
let mut df_security1_handler = None;
|
||||
let mut df_security2 = None;
|
||||
let mut df_security2_handler = None;
|
||||
|
||||
// Obtain SecurityArch protocol and replace handler
|
||||
boot_services
|
||||
.get_handle_for_protocol::<SecurityArch>()
|
||||
.and_then(|h| {
|
||||
.map(|h| {
|
||||
boot_services
|
||||
.open_protocol_exclusive::<SecurityArch>(h)
|
||||
.and_then(|mut security| {
|
||||
.map(|mut security| {
|
||||
df_security1 = Some(core::ptr::addr_of_mut!(security.handler));
|
||||
df_security1_handler = Some(security.handler);
|
||||
security.handler = security_handler as *const c_void;
|
||||
Ok(())
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
info!("security1 unsupported");
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
info!("security1 not found");
|
||||
});
|
||||
})??;
|
||||
|
||||
// Obtain Security2Arch protocol and replace handler
|
||||
boot_services
|
||||
.get_handle_for_protocol::<Security2Arch>()
|
||||
.and_then(|h| {
|
||||
.map(|h| {
|
||||
boot_services
|
||||
.open_protocol_exclusive::<Security2Arch>(h)
|
||||
.and_then(|mut security| {
|
||||
.map(|mut security| {
|
||||
df_security2 = Some(core::ptr::addr_of_mut!(security.handler));
|
||||
df_security2_handler = Some(security.handler);
|
||||
security.handler = security_handler as *const c_void;
|
||||
Ok(())
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
info!("security2 unsupported");
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
info!("security2 not found");
|
||||
});
|
||||
})??;
|
||||
|
||||
// Run the parameter function
|
||||
let x = function();
|
||||
|
||||
// Restore default SecurityArch handler
|
||||
df_security1.and_then(|s1| df_security1_handler.and_then(|s1h| Some(unsafe { *s1 = s1h })));
|
||||
df_security1.and_then(|s1| df_security1_handler.map(|s1h| unsafe { *s1 = s1h }));
|
||||
|
||||
// Restore default SecurityArch2 handler
|
||||
df_security2.and_then(|s2| df_security2_handler.and_then(|s2h| Some(unsafe { *s2 = s2h })));
|
||||
df_security2.and_then(|s2| df_security2_handler.map(|s2h| unsafe { *s2 = s2h }));
|
||||
|
||||
x
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user