SBPF stricter ELF headers
Summary
Imposes more restrictions on what is expected of ELF headers.
Motivation
After the removal of relocations in SIMD-0178 the ELF layout could be massively be simplified by constraining it to a strict subset of what ELF otherwise allows. Doing so not only reduces the complexity of validator implementations but also reduces the attack surface.
Alternatives Considered
Moving away from ELF as a container format altogether. However this would only gain a very small file size advantage but otherwise loose all tooling compatibility.
New Terminology
None.
Detailed Design
The following must go into effect if and only if a program indicates the SBPF-version v3 or higher in its program header (see SIMD-0161).
File header
The file size must not be less than size_of::<Elf64Ehdr>() (64 bytes), otherwise ElfParserError::OutOfBounds must be thrown.
e_ident.ei_magmust be[0x7F, 0x45, 0x4C, 0x46]e_ident.ei_classmust beELFCLASS64(0x02)e_ident.ei_datamust beELFDATA2LSB(0x01)e_ident.ei_versionmust beEV_CURRENT(0x01)e_ident.ei_osabimust beELFOSABI_NONE(0x00)e_ident.ei_abiversionmust be0x00e_ident.ei_padmust be[0x00; 7]e_typeis not checkede_machinemust beEM_BPF(0x00F7)e_versionmust beEV_CURRENT(0x00000001)e_entrymust be within the bounds of the second program headere_phoffmust besize_of::<Elf64Ehdr>()(64 bytes)e_shoffis not checkede_flagssee SIMD-0161e_ehsizemust besize_of::<Elf64Ehdr>()(64 bytes)e_phnummust be greater than or equal0x0001e_phoff + e_phnum * size_of::<Elf64Phdr>()must be less than or equal the file sizee_phentsizemust besize_of::<Elf64Phdr>()(56 bytes)e_shnumis not checkede_shentsizeis not checkede_shstrndxis not checked
If any check fails ElfParserError::InvalidFileHeader must be thrown.
Program headers
| index | purpose | p_flags | p_vaddr |
|---|---|---|---|
| 0 | ro data | PF_R | 0 << 32 |
| 1 | bytecode | PF_X | 1 << 32 |
If p_flags of the first program header is not PF_R, then only the second program header is expected (effectively skipping the first). For each of these predefined program headers:
p_typemust bePT_LOADp_flagsmust match thep_flagsof the entry in the table abovep_offsetbee_phoff + e_phnum * size_of::<Elf64Phdr>()for the first entry and bep_offset + p_fileszof the previous entry for all subsequent entriesp_offsetmust be less than or equalfile.len() as u64p_offsetmust be evenly divisible by 8 bytes,p_vaddrmust match thep_vaddrof the entry in the table abovep_paddrmust match thep_vaddrof the entry in the table abovep_fileszmust bep_memszp_fileszmust not be greater thanfile.len() as u64 - p_offsetp_fileszmust be evenly divisible by 8 bytes,p_memszmust fit in 32 bits / be less than1 << 32p_alignis ignored
If any check fails ElfParserError::InvalidProgramHeader must be thrown.
Impact
The toolchain linker will use a new linker script to adhere to these restrictions defined here and thus the change will be transparent to the dApp developers.
The section headers are ignored so arbitrary metadata can continue to be encoded there.
Security Considerations
None.