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