Skip to content

Commit

Permalink
Adjusts the tests accordingly.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Jul 6, 2023
1 parent 99e663d commit 5d945b9
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 99 deletions.
200 changes: 106 additions & 94 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,9 @@ mod test {
fn new_section(sh_addr: u64, sh_size: u64) -> Elf64Shdr {
Elf64Shdr {
sh_addr,
sh_offset: sh_addr,
sh_offset: sh_addr
.checked_sub(ebpf::MM_PROGRAM_START)
.unwrap_or(sh_addr),
sh_size,
sh_name: 0,
sh_type: 0,
Expand Down Expand Up @@ -1796,7 +1798,7 @@ mod test {
assert!(matches!(
ElfExecutable::parse_ro_sections(
&config,
&SBPFVersion::V2,
&SBPFVersion::V1,
sections,
&elf_bytes,
),
Expand All @@ -1823,7 +1825,7 @@ mod test {
assert!(matches!(
ElfExecutable::parse_ro_sections(
&config,
&SBPFVersion::V2,
&SBPFVersion::V1,
sections,
&elf_bytes,
),
Expand Down Expand Up @@ -1901,7 +1903,7 @@ mod test {
let sections: [(Option<&[u8]>, &Elf64Shdr); 2] =
[(Some(b".text"), &s1), (Some(b".rodata"), &s2)];
assert_eq!(
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes,),
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes),
Err(ElfError::ValueOutOfBounds)
);
}
Expand All @@ -1923,7 +1925,7 @@ mod test {
let sections: [(Option<&[u8]>, &Elf64Shdr); 2] =
[(Some(b".text"), &s1), (Some(b".rodata"), &s2)];
assert_eq!(
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes,),
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes),
Ok(Section::Borrowed(10, 100..120))
);
}
Expand All @@ -1944,7 +1946,7 @@ mod test {
(Some(b".rodata"), &s3),
];
let ro_section =
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes)
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V1, sections, &elf_bytes)
.unwrap();
let ro_region = get_ro_region(&ro_section, &elf_bytes);
let owned_section = match &ro_section {
Expand Down Expand Up @@ -2026,7 +2028,7 @@ mod test {
(Some(b".rodata"), &s3),
];
let ro_section =
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes)
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V1, sections, &elf_bytes)
.unwrap();
let owned_section = match &ro_section {
Section::Owned(_offset, data) => data.as_slice(),
Expand Down Expand Up @@ -2097,107 +2099,117 @@ mod test {
fn test_borrowed_ro_sections() {
let config = Config::default();
let elf_bytes = [0u8; 512];

let s1 = new_section(0, 10);
let s2 = new_section(20, 10);
let s3 = new_section(40, 10);
let s4 = new_section(50, 10);

let sections: [(Option<&[u8]>, &Elf64Shdr); 4] = [
(Some(b".dynsym"), &s1),
(Some(b".text"), &s2),
(Some(b".rodata"), &s3),
(Some(b".dynamic"), &s4),
];
assert_eq!(
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes,),
Ok(Section::Borrowed(20, 20..50))
);
for (vaddr_base, sbpf_version) in [
(0, SBPFVersion::V1),
(ebpf::MM_PROGRAM_START, SBPFVersion::V2),
] {
let s1 = new_section(vaddr_base, 10);
let s2 = new_section(vaddr_base + 20, 10);
let s3 = new_section(vaddr_base + 40, 10);
let s4 = new_section(vaddr_base + 50, 10);
let sections: [(Option<&[u8]>, &Elf64Shdr); 4] = [
(Some(b".dynsym"), &s1),
(Some(b".text"), &s2),
(Some(b".rodata"), &s3),
(Some(b".dynamic"), &s4),
];
assert_eq!(
ElfExecutable::parse_ro_sections(&config, &sbpf_version, sections, &elf_bytes),
Ok(Section::Borrowed(20, 20..50))
);
}
}

#[test]
fn test_borrowed_ro_region_no_initial_gap() {
let config = Config::default();
let elf_bytes = [0u8; 512];
for (vaddr_base, sbpf_version) in [
(0, SBPFVersion::V1),
(ebpf::MM_PROGRAM_START, SBPFVersion::V2),
] {
let s1 = new_section(vaddr_base, 10);
let s2 = new_section(vaddr_base + 10, 10);
let s3 = new_section(vaddr_base + 20, 10);
let sections: [(Option<&[u8]>, &Elf64Shdr); 3] = [
(Some(b".text"), &s1),
(Some(b".rodata"), &s2),
(Some(b".dynamic"), &s3),
];
let ro_section =
ElfExecutable::parse_ro_sections(&config, &sbpf_version, sections, &elf_bytes)
.unwrap();
let ro_region = get_ro_region(&ro_section, &elf_bytes);

// s1 starts at sh_offset=0 so [0..s2.sh_offset + s2.sh_size]
// is the valid ro memory area
assert!(matches!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s1.sh_offset, s2.sh_offset + s2.sh_size),
ProgramResult::Ok(ptr) if ptr == elf_bytes.as_ptr() as u64,
));

let s1 = new_section(0, 10);
let s2 = new_section(10, 10);
let s3 = new_section(10, 10);

let sections: [(Option<&[u8]>, &Elf64Shdr); 3] = [
(Some(b".text"), &s1),
(Some(b".rodata"), &s2),
(Some(b".dynamic"), &s3),
];
let ro_section =
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes)
.unwrap();
let ro_region = get_ro_region(&ro_section, &elf_bytes);

// s1 starts at sh_addr=0 so [0..s2.sh_addr + s2.sh_size] is the valid
// ro memory area
assert!(matches!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START, s2.sh_addr + s2.sh_size),
ProgramResult::Ok(ptr) if ptr == elf_bytes.as_ptr() as u64,
));

// one byte past the ro section is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s2.sh_addr + s2.sh_size, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + s2.sh_addr + s2.sh_size
);
// one byte past the ro section is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s3.sh_offset, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + s3.sh_offset
);
}
}

#[test]
fn test_borrowed_ro_region_initial_gap() {
let config = Config::default();
let elf_bytes = [0u8; 512];
let s1 = new_section(0, 10);
let s2 = new_section(10, 10);
let s3 = new_section(20, 10);

let sections: [(Option<&[u8]>, &Elf64Shdr); 3] = [
(Some(b".dynamic"), &s1),
(Some(b".text"), &s2),
(Some(b".rodata"), &s3),
];
let ro_section =
ElfExecutable::parse_ro_sections(&config, &SBPFVersion::V2, sections, &elf_bytes)
.unwrap();
let ro_region = get_ro_region(&ro_section, &elf_bytes);

// s2 starts at sh_addr=10 so [0..10] is not mappable

// the low bound of the initial gap is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START
);

// the hi bound of the initial gap is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s2.sh_addr - 1, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + 9
);

// [s2.sh_addr..s3.sh_addr + s3.sh_size] is the valid ro memory area
assert!(matches!(
ro_region.vm_to_host(
ebpf::MM_PROGRAM_START + s2.sh_addr,
s3.sh_addr + s3.sh_size - s2.sh_addr
),
ProgramResult::Ok(ptr) if ptr == elf_bytes[s2.sh_addr as usize..].as_ptr() as u64,
));
for (vaddr_base, sbpf_version) in [
(0, SBPFVersion::V1),
(ebpf::MM_PROGRAM_START, SBPFVersion::V2),
] {
let s1 = new_section(vaddr_base, 10);
let s2 = new_section(vaddr_base + 10, 10);
let s3 = new_section(vaddr_base + 20, 10);
let sections: [(Option<&[u8]>, &Elf64Shdr); 3] = [
(Some(b".dynamic"), &s1),
(Some(b".text"), &s2),
(Some(b".rodata"), &s3),
];
let ro_section =
ElfExecutable::parse_ro_sections(&config, &sbpf_version, sections, &elf_bytes)
.unwrap();
let ro_region = get_ro_region(&ro_section, &elf_bytes);

// s2 starts at sh_addr=10 so [0..10] is not mappable

// the low bound of the initial gap is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s1.sh_offset, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + s1.sh_offset
);

// the hi bound of the initial gap is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s2.sh_offset - 1, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + s2.sh_offset - 1
);

// [s2.sh_offset..s3.sh_offset + s3.sh_size] is the valid ro memory area
assert!(matches!(
ro_region.vm_to_host(
ebpf::MM_PROGRAM_START + s2.sh_offset,
s3.sh_offset + s3.sh_size - s2.sh_offset
),
ProgramResult::Ok(ptr) if ptr == elf_bytes[s2.sh_offset as usize..].as_ptr() as u64,
));

// one byte past the ro section is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s3.sh_addr + s3.sh_size, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + s3.sh_addr + s3.sh_size
);
// one byte past the ro section is not mappable
assert_error!(
ro_region.vm_to_host(ebpf::MM_PROGRAM_START + s3.sh_offset + s3.sh_size, 1),
"InvalidVirtualAddress({})",
ebpf::MM_PROGRAM_START + s3.sh_offset + s3.sh_size
);
}
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions tests/elfs/elf.ld
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SECTIONS
. = SIZEOF_HEADERS;
.text : { *(.text) } :text
.rodata : { *(.rodata*) } :rodata
.data.rel.ro : { *(.data.rel.ro) } :rodata
.dynamic : { *(.dynamic) } :dynamic
.dynsym : { *(.dynsym) } :dynamic
.dynstr : { *(.dynstr) } :dynamic
Expand Down
6 changes: 1 addition & 5 deletions tests/elfs/elfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,7 @@ rm reloc_64_relative.o
rm reloc_64_relative_data.o

"$LLVM_DIR"clang $CC_FLAGS -o reloc_64_relative_data.o -c reloc_64_relative_data.c
"$LLVM_DIR"ld.lld $LD_FLAGS --section-start=.text=0x100000000 -o reloc_64_relative_data.so reloc_64_relative_data.o
rm reloc_64_relative_data.o

"$LLVM_DIR"clang $CC_FLAGS_V1 -o reloc_64_relative_data.o -c reloc_64_relative_data.c
"$LLVM_DIR"ld.lld $LD_FLAGS_V1 -o reloc_64_relative_data_sbpfv1.so reloc_64_relative_data.o
"$LLVM_DIR"ld.lld $LD_FLAGS -o reloc_64_relative_data.so reloc_64_relative_data.o
rm reloc_64_relative_data.o

"$LLVM_DIR"clang $CC_FLAGS -o scratch_registers.o -c scratch_registers.c
Expand Down
Binary file modified tests/elfs/reloc_64_relative_data.so
Binary file not shown.
Binary file modified tests/elfs/struct_func_pointer.so
Binary file not shown.

0 comments on commit 5d945b9

Please sign in to comment.