summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2023-10-11 11:03:21 +0200
committerArd Biesheuvel <ardb@kernel.org>2023-10-11 11:12:34 +0200
commit1f2833888dc054f01052cba0d857c3b5f3891ce6 (patch)
treeebf8d412e3c637b4f7d23b1a80a39fb3e06b6967
parentc3cb6e6084db14dbf29180bb0322223480eb177a (diff)
downloadefilite-1f2833888dc054f01052cba0d857c3b5f3891ce6.tar.gz
WIP peloader
-rw-r--r--src/efi/peloader.rs55
-rw-r--r--src/main.rs4
2 files changed, 38 insertions, 21 deletions
diff --git a/src/efi/peloader.rs b/src/efi/peloader.rs
index 50993f7..7a3af19 100644
--- a/src/efi/peloader.rs
+++ b/src/efi/peloader.rs
@@ -2,6 +2,7 @@
// Copyright 2023 Google LLC
// Author: Ard Biesheuvel <ardb@google.com>
+use crate::EFI_PAGE_MASK;
use crate::efi::memmap;
use crate::{FileLoader, MemoryType, Placement};
@@ -20,6 +21,9 @@ struct DosHeader {
pe_offset: u32,
}
+#[cfg(target_arch = "aarch64")]
+const ARCH_MACHINE_ID: u16 = 0xaa64;
+
#[derive(Copy, Clone, Debug)]
#[repr(C)]
struct PeHeader {
@@ -142,6 +146,11 @@ impl<'a> PeLoader<'a> {
pehdr
);
+ if pehdr.machine != ARCH_MACHINE_ID {
+ debug!("Unsupported machine type 0x{:x?}\n", pehdr.machine);
+ return None;
+ }
+
let section_offset = doshdr.pe_offset + 24 + pehdr.size_of_optional_header as u32;
let section_count = pehdr.number_of_sections as usize;
let sections_size = size_of::<PeSection>() * section_count;
@@ -165,19 +174,21 @@ impl<'a> PeLoader<'a> {
};
trace!("Section headers: {:x?}\n", sections);
- // Insert a dummy section for the header region
- sections.push(PeSection {
- name: [0u8; 8],
- virtual_size: pehdr.size_of_headers,
- virtual_address: 0,
- size_of_raw_data: pehdr.size_of_headers,
- pointer_to_raw_data: 0,
- pointer_to_relocations: 0,
- pointer_to_line_numbers: 0,
- number_of_relocations: 0,
- number_of_line_numbers: 0,
- characteristics: EFI_IMAGE_SCN_MEM_READ,
- });
+ // Insert a dummy RO+XP section for the header region
+ if pehdr.size_of_headers & EFI_PAGE_MASK as u32 == 0 {
+ sections.push(PeSection {
+ name: [0u8; 8],
+ virtual_size: pehdr.size_of_headers,
+ virtual_address: 0,
+ size_of_raw_data: pehdr.size_of_headers,
+ pointer_to_raw_data: 0,
+ pointer_to_relocations: 0,
+ pointer_to_line_numbers: 0,
+ number_of_relocations: 0,
+ number_of_line_numbers: 0,
+ characteristics: EFI_IMAGE_SCN_MEM_READ,
+ });
+ }
for s in sections.iter() {
if (s.pointer_to_raw_data | s.size_of_raw_data) & (pehdr.file_alignment - 1) != 0 {
@@ -223,19 +234,25 @@ impl<'a> PeLoader<'a> {
)?;
for s in self.sections.iter() {
+ let (va, vs, ra, rs) = (
+ s.virtual_address as usize,
+ s.virtual_size as usize,
+ s.pointer_to_raw_data as usize,
+ s.size_of_raw_data as usize,
+ );
unsafe {
self.file_loader
- .load_range(
- buf[s.virtual_address as usize].as_mut_ptr() as *mut (),
- s.pointer_to_raw_data as usize,
- s.size_of_raw_data as usize,
- )
+ .load_range(buf[va].as_mut_ptr() as *mut (), ra, vs.min(rs))
.ok()?;
}
- // TODO zero out remaining space
+ if vs > rs {
+ // Zero init remaining space
+ buf[va+rs..va+vs].fill(MaybeUninit::<u8>::zeroed());
+ }
}
// TODO apply relocations
+ // TODO free pages on failure
Some(PeImage {
pe_loader: self,
diff --git a/src/main.rs b/src/main.rs
index 5ad6d02..accd4e9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -175,7 +175,7 @@ extern "C" fn efilite_main(base: *mut u8, mapped: usize, used: isize, avail: usi
};
let ldr = fwcfg.get_kernel_loader().expect("No kernel image provided");
- let pe_ldr = PeLoader::new(&ldr).unwrap();
+ let pe_ldr = PeLoader::new(&ldr).expect("Unsupported kernel image");
let pe_image = pe_ldr.load(MemoryType::EfiLoaderCode, placement).unwrap();
for s in pe_image.sections() {
@@ -195,7 +195,7 @@ extern "C" fn efilite_main(base: *mut u8, mapped: usize, used: isize, avail: usi
idmap.map_range_(&s.0, f);
idmap.activate();
} else {
- warn!("Cannot remap range {:?}\n", s.0);
+ warn!("Cannot remap range {:x?}\n", s.0);
}
}
}