@@ -1369,7 +1369,7 @@ mod test {
1369
1369
elf_parser:: {
1370
1370
// FIXME consts::{ELFCLASS32, ELFDATA2MSB, ET_REL},
1371
1371
consts:: { ELFCLASS32 , ELFDATA2MSB , ET_REL } ,
1372
- types:: { Elf64Ehdr , Elf64Shdr } ,
1372
+ types:: { Elf64Ehdr , Elf64Shdr , Elf64Sym } ,
1373
1373
SECTION_NAME_LENGTH_MAXIMUM ,
1374
1374
} ,
1375
1375
error:: ProgramResult ,
@@ -1398,6 +1398,99 @@ mod test {
1398
1398
) )
1399
1399
}
1400
1400
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
+
1401
1494
#[ test]
1402
1495
fn test_validate ( ) {
1403
1496
let elf_bytes = std:: fs:: read ( "tests/elfs/relative_call_sbpfv1.so" ) . unwrap ( ) ;
0 commit comments