diff --git a/.gitignore b/.gitignore index 434c879..5250b2b 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.vscode/launch.json b/.vscode/launch.json index eb33f0c..0a5d80c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -102,7 +102,7 @@ "request": "launch", "program": "${workspaceFolder}/tests/elfio_fuzzer", "args": [ - "crash-da39a3ee5e6b4b0d3255bfef95601890afd80709" + "slow-unit-82cabac818b690bc042110f7b073e63462c7553d" ], "cwd": "${workspaceFolder}/tests", } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4352134..2e010ce 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -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" diff --git a/elfio/elfio.hpp b/elfio/elfio.hpp index c5b879f..b5a97b5 100644 --- a/elfio/elfio.hpp +++ b/elfio/elfio.hpp @@ -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(); - Elf_Half num = header->get_sections_num(); - Elf64_Off offset = header->get_sections_offset(); + 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(); @@ -503,7 +511,7 @@ class elfio } } - return num; + return true; } //------------------------------------------------------------------------------ @@ -526,9 +534,17 @@ class elfio //------------------------------------------------------------------------------ bool load_segments( std::istream& stream ) { - Elf_Half entry_size = header->get_segment_entry_size(); - Elf_Half num = header->get_segments_num(); - Elf64_Off offset = header->get_segments_offset(); + 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; @@ -546,11 +562,10 @@ class elfio return false; } - seg->load( stream, - static_cast( offset ) + - static_cast( i ) * entry_size ); - - if ( stream.fail() ) { + if ( !seg->load( stream, static_cast( offset ) + + static_cast( i ) * + entry_size ) || + stream.fail() ) { return false; }