major cleanup

This commit is contained in:
2025-07-02 00:27:56 +02:00
parent 7655b589d6
commit a59b723f4b
7 changed files with 62 additions and 80 deletions

17
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

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

View File

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

View File

@ -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, || {
let handle = run_in_security_override(boot_services, || {
boot_services
.load_image(
image_handle,
LoadImageSource::FromBuffer {
buffer: &*slice_from_raw_parts::<u8>(
buffer: unsafe {
&*slice_from_raw_parts::<u8>(
sections.linux.pointer,
sections.linux.size as usize,
),
)
},
file_path: None,
},
)
.unwrap()
})
};
})?;
let mut linux_image = boot_services
.open_protocol_exclusive::<LoadedImage>(handle)

View File

@ -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),
_ => {}
}
}

View File

@ -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)
}