Skip to content

Commit f72af30

Browse files
committed
Adjusts the e_type, e_machine and program headers.
1 parent 9de690c commit f72af30

File tree

12 files changed

+31
-55
lines changed

12 files changed

+31
-55
lines changed

src/elf.rs

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ impl<C: ContextObject> Executable<C> {
407407
loader: Arc<BuiltinProgram<C>>,
408408
) -> Result<Self, ElfParserError> {
409409
use crate::elf_parser::{
410-
consts::{ELFMAG, EV_CURRENT, PF_R, PF_W, PF_X, PT_LOAD, SHN_UNDEF, STT_FUNC},
410+
consts::{ELFMAG, EV_CURRENT, PF_R, PF_X, PT_LOAD, SHN_UNDEF, STT_FUNC},
411411
types::{Elf64Ehdr, Elf64Shdr, Elf64Sym},
412412
};
413413

@@ -426,8 +426,8 @@ impl<C: ContextObject> Executable<C> {
426426
|| file_header.e_ident.ei_osabi != ELFOSABI_NONE
427427
|| file_header.e_ident.ei_abiversion != 0x00
428428
|| file_header.e_ident.ei_pad != [0x00; 7]
429-
|| file_header.e_type != ET_DYN
430-
|| file_header.e_machine != EM_SBPF
429+
// file_header.e_type
430+
|| file_header.e_machine != EM_BPF
431431
|| file_header.e_version != EV_CURRENT
432432
// file_header.e_entry
433433
|| file_header.e_phoff != mem::size_of::<Elf64Ehdr>() as u64
@@ -444,31 +444,25 @@ impl<C: ContextObject> Executable<C> {
444444
return Err(ElfParserError::InvalidFileHeader);
445445
}
446446

447-
const EXPECTED_PROGRAM_HEADERS: [(u32, u64); 4] = [
448-
(PF_X, ebpf::MM_BYTECODE_START), // byte code
449-
(PF_R, ebpf::MM_RODATA_START), // read only data
450-
(PF_R | PF_W, ebpf::MM_STACK_START), // stack
451-
(PF_R | PF_W, ebpf::MM_HEAP_START), // heap
447+
const EXPECTED_PROGRAM_HEADERS: [(u32, u64); 2] = [
448+
(PF_R, 0), // read only data
449+
(PF_X, 1), // byte code
452450
];
453451
let program_header_table =
454452
Elf64::slice_from_bytes::<Elf64Phdr>(elf_bytes, program_header_table_range.clone())?;
455-
for (program_header, (p_flags, p_vaddr)) in program_header_table
453+
for (program_header, (p_flags, p_index)) in program_header_table
456454
.iter()
457455
.zip(EXPECTED_PROGRAM_HEADERS.iter())
458456
{
459-
let p_filesz = if (*p_flags & PF_W) != 0 {
460-
0
461-
} else {
462-
program_header.p_memsz
463-
};
457+
let p_vaddr = p_index * ebpf::MM_REGION_SIZE;
464458
if program_header.p_type != PT_LOAD
465459
|| program_header.p_flags != *p_flags
466460
|| program_header.p_offset < program_header_table_range.end as u64
467461
|| program_header.p_offset >= elf_bytes.len() as u64
468462
|| program_header.p_offset.checked_rem(ebpf::INSN_SIZE as u64) != Some(0)
469-
|| program_header.p_vaddr != *p_vaddr
470-
|| program_header.p_paddr != *p_vaddr
471-
|| program_header.p_filesz != p_filesz
463+
|| program_header.p_vaddr != p_vaddr
464+
|| program_header.p_paddr != p_vaddr
465+
|| program_header.p_filesz != program_header.p_memsz
472466
|| program_header.p_filesz
473467
> (elf_bytes.len() as u64).saturating_sub(program_header.p_offset)
474468
|| program_header.p_filesz.checked_rem(ebpf::INSN_SIZE as u64) != Some(0)
@@ -478,8 +472,8 @@ impl<C: ContextObject> Executable<C> {
478472
}
479473
}
480474

481-
let bytecode_header = &program_header_table[0];
482-
let rodata_header = &program_header_table[1];
475+
let rodata_header = &program_header_table[0];
476+
let bytecode_header = &program_header_table[1];
483477
let text_section_vaddr = bytecode_header.p_vaddr;
484478
let text_section_range = bytecode_header.file_range().unwrap_or_default();
485479
let ro_section = Section::Borrowed(
@@ -501,10 +495,6 @@ impl<C: ContextObject> Executable<C> {
501495
.saturating_sub(bytecode_header.p_vaddr)
502496
.checked_div(ebpf::INSN_SIZE as u64)
503497
.unwrap_or_default() as usize;
504-
let entry_insn = ebpf::get_insn(&elf_bytes[text_section_range.clone()], entry_pc);
505-
if !entry_insn.is_function_start_marker() {
506-
return Err(ElfParserError::InvalidFileHeader);
507-
}
508498

509499
let mut function_registry = FunctionRegistry::<usize>::default();
510500
let config = loader.get_config();

tests/elf.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ fn test_strict_header() {
5858
assert_eq!(err, ElfParserError::OutOfBounds);
5959

6060
// Break the file header one byte at a time
61-
let expected_results = std::iter::repeat_n(&Err(ElfParserError::InvalidFileHeader), 40)
61+
let expected_results = std::iter::repeat_n(&Err(ElfParserError::InvalidFileHeader), 16)
62+
.chain(std::iter::repeat_n(&Ok(()), 2))
63+
.chain(std::iter::repeat_n(
64+
&Err(ElfParserError::InvalidFileHeader),
65+
22,
66+
))
6267
.chain(std::iter::repeat_n(&Ok(()), 12))
6368
.chain(std::iter::repeat_n(
6469
&Err(ElfParserError::InvalidFileHeader),
@@ -81,20 +86,9 @@ fn test_strict_header() {
8186
std::iter::repeat_n(&Err(ElfParserError::InvalidProgramHeader), 48)
8287
.chain(std::iter::repeat_n(&Ok(()), 8))
8388
.collect::<Vec<_>>();
84-
let expected_results_writable =
85-
std::iter::repeat_n(&Err(ElfParserError::InvalidProgramHeader), 40)
86-
.chain(std::iter::repeat_n(&Ok(()), 4))
87-
.chain(std::iter::repeat_n(
88-
&Err(ElfParserError::InvalidProgramHeader),
89-
4,
90-
))
91-
.chain(std::iter::repeat_n(&Ok(()), 8))
92-
.collect::<Vec<_>>();
9389
let expected_results = vec![
9490
expected_results_readonly.iter(),
9591
expected_results_readonly.iter(),
96-
expected_results_writable.iter(),
97-
expected_results_writable.iter(),
9892
];
9993
for (header_index, expected_results) in expected_results.into_iter().enumerate() {
10094
for (offset, expected) in (std::mem::size_of::<Elf64Ehdr>()
@@ -114,19 +108,11 @@ fn test_strict_header() {
114108
// Check that an unaligned program header length fails
115109
{
116110
let mut elf_bytes = elf_bytes.clone();
117-
elf_bytes[0x60] = 0x29;
118-
elf_bytes[0x68] = 0x29;
111+
elf_bytes[0x98] = 0x29;
112+
elf_bytes[0xA0] = 0x29;
119113
let err = ElfExecutable::load_with_strict_parser(&elf_bytes, loader.clone()).unwrap_err();
120114
assert_eq!(err, ElfParserError::InvalidProgramHeader);
121115
}
122-
123-
// Check that an entrypoint missing a function start marker fails
124-
{
125-
let mut elf_bytes = elf_bytes.clone();
126-
elf_bytes[0x1B8] = 0x00;
127-
let err = ElfExecutable::load_with_strict_parser(&elf_bytes, loader.clone()).unwrap_err();
128-
assert_eq!(err, ElfParserError::InvalidFileHeader);
129-
}
130116
}
131117

132118
#[test]

tests/elfs/elf.ld

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
SECTIONS
22
{
3-
.text 0x000000000 : {
4-
*(.text*)
5-
} :text
6-
.rodata 0x100000000 : {
3+
.rodata 0x000000000 : {
74
*(.rodata*)
85
*(.data.rel.ro*)
96
BYTE(0);
107
. = ALIGN(8);
118
} :rodata
9+
.text 0x100000000 : {
10+
*(.text*)
11+
} :text
1212
.bss.stack 0x200000000 (NOLOAD) : {
1313
_stack_start = .;
1414
. = . + 0x1000;
@@ -37,8 +37,8 @@ SECTIONS
3737

3838
PHDRS
3939
{
40-
text PT_LOAD FLAGS(1);
4140
rodata PT_LOAD FLAGS(4);
41+
text PT_LOAD FLAGS(1);
4242
stack PT_LOAD FLAGS(6);
4343
heap PT_LOAD FLAGS(6);
4444
dynsym PT_NULL FLAGS(0);

tests/elfs/relative_call.so

0 Bytes
Binary file not shown.

tests/elfs/reloc_64_64.so

0 Bytes
Binary file not shown.

tests/elfs/reloc_64_relative.so

0 Bytes
Binary file not shown.
-8 Bytes
Binary file not shown.

tests/elfs/rodata_section.so

0 Bytes
Binary file not shown.

tests/elfs/strict_header.so

100755100644
0 Bytes
Binary file not shown.

tests/elfs/struct_func_pointer.so

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)