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/elfio_fuzzer
tests/corpus
examples/writer/hello_x86_64
examples/write_obj/hello

2
.vscode/launch.json vendored
View File

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

24
.vscode/tasks.json vendored
View File

@ -56,6 +56,30 @@
"problemMatcher": [
"$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"

View File

@ -473,12 +473,20 @@ class elfio
}
//------------------------------------------------------------------------------
Elf_Half load_sections( std::istream& stream )
bool load_sections( std::istream& stream )
{
unsigned char file_class = header->get_class();
Elf_Half entry_size = header->get_section_entry_size();
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 ) {
section* sec = create_section();
sec->load( stream,
@ -503,7 +511,7 @@ class elfio
}
}
return num;
return true;
}
//------------------------------------------------------------------------------
@ -526,10 +534,18 @@ class elfio
//------------------------------------------------------------------------------
bool load_segments( std::istream& stream )
{
unsigned char file_class = header->get_class();
Elf_Half entry_size = header->get_segment_entry_size();
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 ) {
segment* seg = nullptr;
unsigned char file_class = header->get_class();
@ -546,11 +562,10 @@ class elfio
return false;
}
seg->load( stream,
static_cast<std::streamoff>( offset ) +
static_cast<std::streampos>( i ) * entry_size );
if ( stream.fail() ) {
if ( !seg->load( stream, static_cast<std::streamoff>( offset ) +
static_cast<std::streampos>( i ) *
entry_size ) ||
stream.fail() ) {
return false;
}