Skip to content

Commit f633b78

Browse files
committed
chore: added arch expected machine in kernel boot path
1 parent 070bc97 commit f633b78

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

‎src/pe/fixtures.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
use object::pe::IMAGE_DIRECTORY_ENTRY_BASERELOC;
44

5+
use super::kernel::EXPECTED_MACHINE;
6+
57
pub(crate) const FILE_ALIGN_U32: u32 = 0x200;
68

79
const FILE_ALIGN: usize = 0x200;
@@ -26,7 +28,7 @@ impl Builder {
2628
Self::write_bytes(&mut data, NT_OFFSET, b"PE");
2729

2830
let file_header = Self::offset(NT_OFFSET, 4);
29-
Self::write_u16(&mut data, file_header, 0x8664);
31+
Self::write_u16(&mut data, file_header, EXPECTED_MACHINE);
3032
Self::write_u16(&mut data, Self::offset(file_header, 16), 0xF0);
3133
Self::write_u16(&mut data, Self::offset(file_header, 18), 0x0002);
3234

@@ -105,6 +107,10 @@ impl Builder {
105107
);
106108
}
107109

110+
pub(crate) fn set_machine(&mut self, value: u16) {
111+
Self::write_u16(&mut self.data, Self::offset(NT_OFFSET, 4), value);
112+
}
113+
108114
pub(crate) fn set_last_ptr_relocs(&mut self, ptr: u32) {
109115
let section_header = self.last_section_header_offset();
110116
Self::write_u32(&mut self.data, Self::offset(section_header, 24), ptr);

‎src/pe/kernel.rs‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ use object::pe::{
99
};
1010
use object::read::pe::{ImageNtHeaders as _, SectionTable};
1111

12+
/// `IMAGE_FILE_MACHINE` value required for kernels loaded by this target.
13+
#[cfg(target_arch = "x86_64")]
14+
pub(crate) const EXPECTED_MACHINE: u16 = object::pe::IMAGE_FILE_MACHINE_AMD64;
15+
/// `IMAGE_FILE_MACHINE` value required for kernels loaded by this target.
16+
#[cfg(target_arch = "aarch64")]
17+
pub(crate) const EXPECTED_MACHINE: u16 = object::pe::IMAGE_FILE_MACHINE_ARM64;
18+
/// `IMAGE_FILE_MACHINE` value required for kernels loaded by this target.
19+
#[cfg(target_arch = "riscv64")]
20+
pub(crate) const EXPECTED_MACHINE: u16 = object::pe::IMAGE_FILE_MACHINE_RISCV64;
21+
1222
/// `IMAGE_DLLCHARACTERISTICS_NX_COMPAT`.
1323
const NX_COMPAT: u16 = 0x0100;
1424

@@ -42,6 +52,13 @@ impl<'a> Image<'a> {
4252
.sections(data, offset)
4353
.context("invalid section table")?;
4454

55+
let machine = nt_headers.file_header.machine.get(LE);
56+
ensure!(
57+
machine == EXPECTED_MACHINE,
58+
"kernel PE machine 0x{machine:04x} is not supported on this target \
59+
(expected 0x{EXPECTED_MACHINE:04x})"
60+
);
61+
4562
let optional_header = &nt_headers.optional_header;
4663
let entry_point_rva = optional_header.address_of_entry_point.get(LE);
4764
let base_address = optional_header.image_base.get(LE);
@@ -127,6 +144,21 @@ mod tests {
127144
assert!(err.to_string().contains("invalid PE headers"), "{err}");
128145
}
129146

147+
#[test]
148+
fn parse_wrong_machine_rejected() {
149+
// ARRANGE
150+
let mut builder = Builder::new();
151+
builder.add_section(*b".text\0\0\0", &[0_u8; 16]);
152+
builder.set_machine(0);
153+
let data = builder.build();
154+
155+
// ACT
156+
let err = Image::parse(&data).unwrap_err();
157+
158+
// ASSERT
159+
assert!(err.to_string().contains("machine"), "{err}");
160+
}
161+
130162
#[test]
131163
fn parse_no_entry_point() {
132164
// ARRANGE

0 commit comments

Comments
 (0)