validate elf header

This commit is contained in:
2025-11-21 12:18:15 -07:00
parent 6e88feb9a7
commit 1a97ad57cf

View File

@@ -8,12 +8,12 @@ use core::ptr;
use embedded_sdmmc::ShortFileName; use embedded_sdmmc::ShortFileName;
use goblin::{ use goblin::{
elf::{ elf::{
header::header32::Header, header::{EM_ARM, ET_DYN, EV_CURRENT, header32::Header},
program_header::program_header32::{PT_LOAD, ProgramHeader}, program_header::program_header32::{PT_LOAD, ProgramHeader},
reloc::R_ARM_RELATIVE, reloc::R_ARM_RELATIVE,
section_header::{SHT_REL, SHT_SYMTAB}, section_header::{SHT_REL, SHT_SYMTAB},
}, },
elf32::{header, reloc::Rel, section_header::SectionHeader, sym::Sym}, elf32::{reloc::Rel, section_header::SectionHeader, sym::Sym},
}; };
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use userlib_sys::{EntryFn, SyscallTable}; use userlib_sys::{EntryFn, SyscallTable};
@@ -22,6 +22,8 @@ const ELF32_HDR_SIZE: usize = 52;
#[derive(Debug)] #[derive(Debug)]
pub enum LoadError { pub enum LoadError {
WrongMachine,
InvalidElf,
FailedToReadFile, FailedToReadFile,
ElfIsNotPie, ElfIsNotPie,
UnknownRelocationType, UnknownRelocationType,
@@ -39,10 +41,7 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Result<(EntryFn, Bump),
.map_err(|_| LoadError::FailedToReadFile)?; .map_err(|_| LoadError::FailedToReadFile)?;
let elf_header = Header::from_bytes(&header_buf); let elf_header = Header::from_bytes(&header_buf);
// reject non-PIE validate_header(&elf_header)?;
if elf_header.e_type != header::ET_DYN {
return Err(LoadError::ElfIsNotPie);
}
let mut ph_buf = vec![0_u8; elf_header.e_phentsize as usize]; let mut ph_buf = vec![0_u8; elf_header.e_phentsize as usize];
@@ -89,6 +88,19 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Result<(EntryFn, Bump),
.map_err(|_| LoadError::FailedToReadFile)? .map_err(|_| LoadError::FailedToReadFile)?
} }
fn validate_header(h: &Header) -> Result<(), LoadError> {
if h.e_type != ET_DYN {
return Err(LoadError::ElfIsNotPie);
}
if h.e_machine != EM_ARM {
return Err(LoadError::WrongMachine);
}
if h.e_version as u8 != EV_CURRENT {
return Err(LoadError::InvalidElf);
}
Ok(())
}
fn load_segment(file: &mut File, ph: &ProgramHeader, segment: &mut [u8]) -> Result<(), LoadError> { fn load_segment(file: &mut File, ph: &ProgramHeader, segment: &mut [u8]) -> Result<(), LoadError> {
let filesz = ph.p_filesz as usize; let filesz = ph.p_filesz as usize;
let memsz = ph.p_memsz as usize; let memsz = ph.p_memsz as usize;