Add check for incorrect section/segment entry size

This commit is contained in:
Serge Lamikhov-Center 2022-06-18 22:47:37 +03:00
parent 90737d9937
commit 3aad501f5b
4 changed files with 54 additions and 14 deletions

1
.gitignore vendored
View File

@ -43,6 +43,7 @@ tests/elf_examples/test_symbols_order.elf
tests/elf_examples/zavl_gen.ko tests/elf_examples/zavl_gen.ko
tests/elfio_fuzzer tests/elfio_fuzzer
tests/corpus
examples/writer/hello_x86_64 examples/writer/hello_x86_64
examples/write_obj/hello examples/write_obj/hello

2
.vscode/launch.json vendored
View File

@ -102,7 +102,7 @@
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/tests/elfio_fuzzer", "program": "${workspaceFolder}/tests/elfio_fuzzer",
"args": [ "args": [
"crash-da39a3ee5e6b4b0d3255bfef95601890afd80709" "slow-unit-82cabac818b690bc042110f7b073e63462c7553d"
], ],
"cwd": "${workspaceFolder}/tests", "cwd": "${workspaceFolder}/tests",
} }

24
.vscode/tasks.json vendored
View File

@ -56,6 +56,30 @@
"problemMatcher": [ "problemMatcher": [
"$gcc" "$gcc"
] ]
},
{
"type": "shell",
"label": "Fuzzer",
"command": "clang",
"args": [
"-g",
"-O0",
"-fsanitize=fuzzer",
"-I..",
"elfio_fuzzer.cpp",
"-o",
"elfio_fuzzer",
],
"options": {
"cwd": "${workspaceRoot}/tests"
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
} }
], ],
"version": "2.0.0" "version": "2.0.0"

View File

@ -473,11 +473,19 @@ class elfio
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half load_sections( std::istream& stream ) bool load_sections( std::istream& stream )
{ {
Elf_Half entry_size = header->get_section_entry_size(); unsigned char file_class = header->get_class();
Elf_Half num = header->get_sections_num(); Elf_Half entry_size = header->get_section_entry_size();
Elf64_Off offset = header->get_sections_offset(); Elf_Half num = header->get_sections_num();
Elf64_Off offset = header->get_sections_offset();
if ( ( num != 0 && file_class == ELFCLASS64 &&
entry_size < sizeof( Elf64_Shdr ) ) ||
( num != 0 && file_class == ELFCLASS32 &&
entry_size < sizeof( Elf32_Shdr ) ) ) {
return false;
}
for ( Elf_Half i = 0; i < num; ++i ) { for ( Elf_Half i = 0; i < num; ++i ) {
section* sec = create_section(); section* sec = create_section();
@ -503,7 +511,7 @@ class elfio
} }
} }
return num; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -526,9 +534,17 @@ class elfio
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool load_segments( std::istream& stream ) bool load_segments( std::istream& stream )
{ {
Elf_Half entry_size = header->get_segment_entry_size(); unsigned char file_class = header->get_class();
Elf_Half num = header->get_segments_num(); Elf_Half entry_size = header->get_segment_entry_size();
Elf64_Off offset = header->get_segments_offset(); Elf_Half num = header->get_segments_num();
Elf64_Off offset = header->get_segments_offset();
if ( ( num != 0 && file_class == ELFCLASS64 &&
entry_size < sizeof( Elf64_Phdr ) ) ||
( num != 0 && file_class == ELFCLASS32 &&
entry_size < sizeof( Elf32_Phdr ) ) ) {
return false;
}
for ( Elf_Half i = 0; i < num; ++i ) { for ( Elf_Half i = 0; i < num; ++i ) {
segment* seg = nullptr; segment* seg = nullptr;
@ -546,11 +562,10 @@ class elfio
return false; return false;
} }
seg->load( stream, if ( !seg->load( stream, static_cast<std::streamoff>( offset ) +
static_cast<std::streamoff>( offset ) + static_cast<std::streampos>( i ) *
static_cast<std::streampos>( i ) * entry_size ); entry_size ) ||
stream.fail() ) {
if ( stream.fail() ) {
return false; return false;
} }