@@ -1381,7 +1381,7 @@ mod test {
13811381 elf_parser:: {
13821382 // FIXME consts::{ELFCLASS32, ELFDATA2MSB, ET_REL},
13831383 consts:: { ELFCLASS32 , ELFDATA2MSB , ET_REL } ,
1384- types:: { Elf64Ehdr , Elf64Shdr } ,
1384+ types:: { Elf64Ehdr , Elf64Shdr , Elf64Sym } ,
13851385 SECTION_NAME_LENGTH_MAXIMUM ,
13861386 } ,
13871387 error:: ProgramResult ,
@@ -1410,6 +1410,137 @@ mod test {
14101410 ) )
14111411 }
14121412
1413+ #[ test]
1414+ fn test_strict_header ( ) {
1415+ let elf_bytes =
1416+ std:: fs:: read ( "tests/elfs/strict_header.so" ) . expect ( "failed to read elf file" ) ;
1417+ let loader = loader ( ) ;
1418+
1419+ // Check that the unmodified file can be parsed
1420+ {
1421+ let loader = Arc :: new ( BuiltinProgram :: new_loader (
1422+ Config {
1423+ enable_symbol_and_section_labels : true ,
1424+ ..Config :: default ( )
1425+ } ,
1426+ FunctionRegistry :: < BuiltinFunction < TestContextObject > > :: default ( ) ,
1427+ ) ) ;
1428+ let executable = ElfExecutable :: load ( & elf_bytes, loader. clone ( ) ) . unwrap ( ) ;
1429+ let ( name, _pc) = executable. get_function_registry ( ) . lookup_by_key ( 4 ) . unwrap ( ) ;
1430+ assert_eq ! ( name, b"entrypoint" ) ;
1431+ }
1432+
1433+ // Check that using a reserved SBPF version fails
1434+ {
1435+ let mut elf_bytes = elf_bytes. clone ( ) ;
1436+ elf_bytes[ 0x0030 ] = 0xFF ;
1437+ let err = ElfExecutable :: load ( & elf_bytes, loader. clone ( ) ) . unwrap_err ( ) ;
1438+ assert_eq ! ( err, ElfError :: UnsupportedSBPFVersion ) ;
1439+ }
1440+
1441+ // Check that an empty file fails
1442+ let err = ElfExecutable :: load_with_strict_parser ( & [ ] , loader. clone ( ) ) . unwrap_err ( ) ;
1443+ assert_eq ! ( err, ElfParserError :: OutOfBounds ) ;
1444+
1445+ // Break the file header one byte at a time
1446+ let expected_results = std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) )
1447+ . take ( 40 )
1448+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 12 ) )
1449+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) ) . take ( 4 ) )
1450+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) ) . take ( 1 ) )
1451+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) ) . take ( 3 ) )
1452+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 2 ) )
1453+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) ) . take ( 2 ) ) ;
1454+ for ( offset, expected) in ( 0 ..std:: mem:: size_of :: < Elf64Ehdr > ( ) ) . zip ( expected_results) {
1455+ let mut elf_bytes = elf_bytes. clone ( ) ;
1456+ elf_bytes[ offset] = 0xAF ;
1457+ let result =
1458+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . map ( |_| ( ) ) ;
1459+ assert_eq ! ( & result, expected) ;
1460+ }
1461+
1462+ // Break the program header table one byte at a time
1463+ let expected_results_readonly =
1464+ std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) )
1465+ . take ( 48 )
1466+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 8 ) )
1467+ . collect :: < Vec < _ > > ( ) ;
1468+ let expected_results_writable =
1469+ std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) )
1470+ . take ( 40 )
1471+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 4 ) )
1472+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) ) . take ( 4 ) )
1473+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 8 ) )
1474+ . collect :: < Vec < _ > > ( ) ;
1475+ let expected_results = vec ! [
1476+ expected_results_readonly. iter( ) ,
1477+ expected_results_readonly. iter( ) ,
1478+ expected_results_writable. iter( ) ,
1479+ expected_results_writable. iter( ) ,
1480+ expected_results_readonly. iter( ) ,
1481+ ] ;
1482+ for ( header_index, expected_results) in expected_results. into_iter ( ) . enumerate ( ) {
1483+ for ( offset, expected) in ( std:: mem:: size_of :: < Elf64Ehdr > ( )
1484+ + std:: mem:: size_of :: < Elf64Phdr > ( ) * header_index
1485+ ..std:: mem:: size_of :: < Elf64Ehdr > ( )
1486+ + std:: mem:: size_of :: < Elf64Phdr > ( ) * ( header_index + 1 ) )
1487+ . zip ( expected_results)
1488+ {
1489+ let mut elf_bytes = elf_bytes. clone ( ) ;
1490+ elf_bytes[ offset] = 0xAF ;
1491+ let result =
1492+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . map ( |_| ( ) ) ;
1493+ assert_eq ! ( &&result, expected) ;
1494+ }
1495+ }
1496+
1497+ // Break the dynamic symbol table one byte at a time
1498+ for index in 1 ..3 {
1499+ let expected_results = std:: iter:: repeat ( & Ok ( ( ) ) )
1500+ . take ( 8 )
1501+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: OutOfBounds ) ) . take ( 8 ) )
1502+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidSize ) ) . take ( 1 ) )
1503+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: OutOfBounds ) ) . take ( 7 ) ) ;
1504+ for ( offset, expected) in ( 0x3000 + std:: mem:: size_of :: < Elf64Sym > ( ) * index
1505+ ..0x3000 + std:: mem:: size_of :: < Elf64Sym > ( ) * ( index + 1 ) )
1506+ . zip ( expected_results)
1507+ {
1508+ let mut elf_bytes = elf_bytes. clone ( ) ;
1509+ elf_bytes[ offset] = 0xAF ;
1510+ let result =
1511+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . map ( |_| ( ) ) ;
1512+ assert_eq ! ( & result, expected) ;
1513+ }
1514+ }
1515+
1516+ // Check that an empty function symbol fails
1517+ {
1518+ let mut elf_bytes = elf_bytes. clone ( ) ;
1519+ elf_bytes[ 0x3040 ] = 0x00 ;
1520+ let err =
1521+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . unwrap_err ( ) ;
1522+ assert_eq ! ( err, ElfParserError :: InvalidSize ) ;
1523+ }
1524+
1525+ // Check that bytecode not covered by function symbols fails
1526+ {
1527+ let mut elf_bytes = elf_bytes. clone ( ) ;
1528+ elf_bytes[ 0x3040 ] = 0x08 ;
1529+ let err =
1530+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . unwrap_err ( ) ;
1531+ assert_eq ! ( err, ElfParserError :: OutOfBounds ) ;
1532+ }
1533+
1534+ // Check that an entrypoint not covered by function symbols fails
1535+ {
1536+ let mut elf_bytes = elf_bytes. clone ( ) ;
1537+ elf_bytes[ 0x0018 ] = 0x10 ;
1538+ let err =
1539+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . unwrap_err ( ) ;
1540+ assert_eq ! ( err, ElfParserError :: InvalidFileHeader ) ;
1541+ }
1542+ }
1543+
14131544 #[ test]
14141545 fn test_validate ( ) {
14151546 let elf_bytes = std:: fs:: read ( "tests/elfs/relative_call_sbpfv1.so" ) . unwrap ( ) ;
0 commit comments