@@ -1369,7 +1369,7 @@ mod test {
13691369 elf_parser:: {
13701370 // FIXME consts::{ELFCLASS32, ELFDATA2MSB, ET_REL},
13711371 consts:: { ELFCLASS32 , ELFDATA2MSB , ET_REL } ,
1372- types:: { Elf64Ehdr , Elf64Shdr } ,
1372+ types:: { Elf64Ehdr , Elf64Shdr , Elf64Sym } ,
13731373 SECTION_NAME_LENGTH_MAXIMUM ,
13741374 } ,
13751375 error:: ProgramResult ,
@@ -1398,6 +1398,99 @@ mod test {
13981398 ) )
13991399 }
14001400
1401+ #[ test]
1402+ fn test_strict_header ( ) {
1403+ let elf_bytes =
1404+ std:: fs:: read ( "tests/elfs/strict_header.so" ) . expect ( "failed to read elf file" ) ;
1405+ let loader = loader ( ) ;
1406+
1407+ // Check that the unmodified file can be parsed
1408+ ElfExecutable :: load ( & elf_bytes, loader. clone ( ) ) . unwrap ( ) ;
1409+
1410+ // Check that an empty file fails
1411+ let err = ElfExecutable :: load_with_strict_parser ( & [ ] , loader. clone ( ) ) . unwrap_err ( ) ;
1412+ assert_eq ! ( err, ElfParserError :: OutOfBounds ) ;
1413+
1414+ // Break the file header one byte at a time
1415+ let expected_results = std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) )
1416+ . take ( 40 )
1417+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 12 ) )
1418+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) ) . take ( 4 ) )
1419+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) ) . take ( 1 ) )
1420+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) ) . take ( 3 ) )
1421+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 2 ) )
1422+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidFileHeader ) ) . take ( 2 ) ) ;
1423+ for ( offset, expected) in ( 0 ..std:: mem:: size_of :: < Elf64Ehdr > ( ) ) . zip ( expected_results) {
1424+ let mut elf_bytes = elf_bytes. clone ( ) ;
1425+ elf_bytes[ offset] = 0xAF ;
1426+ let result =
1427+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . map ( |_| ( ) ) ;
1428+ assert_eq ! ( & result, expected) ;
1429+ }
1430+
1431+ // Break the program header table one byte at a time
1432+ let expected_results_readonly =
1433+ std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) )
1434+ . take ( 48 )
1435+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 8 ) )
1436+ . collect :: < Vec < _ > > ( ) ;
1437+ let expected_results_writable =
1438+ std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) )
1439+ . take ( 40 )
1440+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 4 ) )
1441+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidProgramHeader ) ) . take ( 4 ) )
1442+ . chain ( std:: iter:: repeat ( & Ok ( ( ) ) ) . take ( 8 ) )
1443+ . collect :: < Vec < _ > > ( ) ;
1444+ let expected_results = vec ! [
1445+ expected_results_readonly. iter( ) ,
1446+ expected_results_readonly. iter( ) ,
1447+ expected_results_writable. iter( ) ,
1448+ expected_results_writable. iter( ) ,
1449+ expected_results_readonly. iter( ) ,
1450+ ] ;
1451+ for ( header_index, expected_results) in expected_results. into_iter ( ) . enumerate ( ) {
1452+ for ( offset, expected) in ( std:: mem:: size_of :: < Elf64Ehdr > ( )
1453+ + std:: mem:: size_of :: < Elf64Phdr > ( ) * header_index
1454+ ..std:: mem:: size_of :: < Elf64Ehdr > ( )
1455+ + std:: mem:: size_of :: < Elf64Phdr > ( ) * ( header_index + 1 ) )
1456+ . zip ( expected_results)
1457+ {
1458+ let mut elf_bytes = elf_bytes. clone ( ) ;
1459+ elf_bytes[ offset] = 0xAF ;
1460+ let result =
1461+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . map ( |_| ( ) ) ;
1462+ assert_eq ! ( &&result, expected) ;
1463+ }
1464+ }
1465+
1466+ // Break the dynamic symbol table one byte at a time
1467+ for index in 1 ..3 {
1468+ let expected_results = std:: iter:: repeat ( & Ok ( ( ) ) )
1469+ . take ( 8 )
1470+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: OutOfBounds ) ) . take ( 8 ) )
1471+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: InvalidSize ) ) . take ( 1 ) )
1472+ . chain ( std:: iter:: repeat ( & Err ( ElfParserError :: OutOfBounds ) ) . take ( 7 ) ) ;
1473+ for ( offset, expected) in ( 0x3000 + std:: mem:: size_of :: < Elf64Sym > ( ) * index
1474+ ..0x3000 + std:: mem:: size_of :: < Elf64Sym > ( ) * ( index + 1 ) )
1475+ . zip ( expected_results)
1476+ {
1477+ let mut elf_bytes = elf_bytes. clone ( ) ;
1478+ elf_bytes[ offset] = 0xAF ;
1479+ let result =
1480+ ElfExecutable :: load_with_strict_parser ( & elf_bytes, loader. clone ( ) ) . map ( |_| ( ) ) ;
1481+ assert_eq ! ( & result, expected) ;
1482+ }
1483+ }
1484+
1485+ // Check that an empty function symbol fails
1486+ let mut elf_bytes = elf_bytes. clone ( ) ;
1487+ elf_bytes[ 0x3040 ] = 0x00 ;
1488+ assert_eq ! (
1489+ ElfExecutable :: load_with_strict_parser( & elf_bytes, loader. clone( ) ) . unwrap_err( ) ,
1490+ ElfParserError :: InvalidSize
1491+ ) ;
1492+ }
1493+
14011494 #[ test]
14021495 fn test_validate ( ) {
14031496 let elf_bytes = std:: fs:: read ( "tests/elfs/relative_call_sbpfv1.so" ) . unwrap ( ) ;
0 commit comments