diff --git a/.vscode/launch.json b/.vscode/launch.json index 9e8f8c7..eb33f0c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,7 +34,7 @@ "request": "launch", "program": "${workspaceFolder}/build/examples/elfdump/elfdump", "args": [ - "tests/elf_examples/hello_32" + "tests/slow-unit-98e0b3724bca5039b0c12d9e31f6afcbe4f3ce64" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", @@ -60,7 +60,6 @@ "11706", "/usr/bin/bash" ], - "sudo": true, "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], @@ -83,7 +82,6 @@ "args": [ "/proc/kcore" ], - "sudo": true, "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], @@ -97,6 +95,16 @@ } ], "miDebuggerPath": "/home/user/ELFIO/examples/sudo_gdb.sh" + }, + { + "name": "Fuzzer", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/tests/elfio_fuzzer", + "args": [ + "crash-da39a3ee5e6b4b0d3255bfef95601890afd80709" + ], + "cwd": "${workspaceFolder}/tests", } ] } \ No newline at end of file diff --git a/elfio/elfio.hpp b/elfio/elfio.hpp index c6a4f25..c5b879f 100644 --- a/elfio/elfio.hpp +++ b/elfio/elfio.hpp @@ -172,8 +172,8 @@ class elfio return false; } - load_sections( stream ); - bool is_still_good = load_segments( stream ); + bool is_still_good = load_sections( stream ); + is_still_good = is_still_good && load_segments( stream ); return is_still_good; } diff --git a/elfio/elfio_section.hpp b/elfio/elfio_section.hpp index a71559a..5874859 100644 --- a/elfio/elfio_section.hpp +++ b/elfio/elfio_section.hpp @@ -62,7 +62,7 @@ class section ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_SET_ACCESS_DECL( Elf_Half, index ); - virtual void load( std::istream& stream, std::streampos header_offset ) = 0; + virtual bool load( std::istream& stream, std::streampos header_offset ) = 0; virtual void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) = 0; @@ -201,7 +201,7 @@ template class section_impl : public section void set_index( Elf_Half value ) override { index = value; } //------------------------------------------------------------------------------ - void load( std::istream& stream, std::streampos header_offset ) override + bool load( std::istream& stream, std::streampos header_offset ) override { std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); @@ -226,6 +226,11 @@ template class section_impl : public section stream.seekg( ( *translator )[( *convertor )( header.sh_offset )] ); stream.read( data, size ); + if (stream.gcount() != size) { + delete[] data; + data = nullptr; + return false; + } data[size] = 0; // Ensure data is ended with 0 to avoid oob read data_size = decltype( data_size )( size ); } @@ -233,6 +238,8 @@ template class section_impl : public section data_size = 0; } } + + return true; } //------------------------------------------------------------------------------ diff --git a/elfio/elfio_segment.hpp b/elfio/elfio_segment.hpp index bc6114f..b8b9809 100644 --- a/elfio/elfio_segment.hpp +++ b/elfio/elfio_segment.hpp @@ -61,7 +61,7 @@ class segment ELFIO_SET_ACCESS_DECL( Elf_Half, index ); virtual const std::vector& get_sections() const = 0; - virtual void load( std::istream& stream, std::streampos header_offset ) = 0; + virtual bool load( std::istream& stream, std::streampos header_offset ) = 0; virtual void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) = 0; @@ -159,7 +159,7 @@ template class segment_impl : public segment void set_index( Elf_Half value ) override { index = value; } //------------------------------------------------------------------------------ - void load( std::istream& stream, std::streampos header_offset ) override + bool load( std::istream& stream, std::streampos header_offset ) override { if ( translator->empty() ) { stream.seekg( 0, stream.end ); @@ -185,10 +185,17 @@ template class segment_impl : public segment if ( nullptr != data ) { stream.read( data, size ); + if (stream.gcount() != size) { + delete[] data; + data = nullptr; + return false; + } data[size] = 0; } } } + + return true; } //------------------------------------------------------------------------------ diff --git a/tests/elfio_fuzzer.cpp b/tests/elfio_fuzzer.cpp new file mode 100644 index 0000000..8154a11 --- /dev/null +++ b/tests/elfio_fuzzer.cpp @@ -0,0 +1,16 @@ +#include +#include + +#include +using namespace ELFIO; + +extern "C" int LLVMFuzzerTestOneInput( const uint8_t* Data, size_t Size ) +{ + std::string str( (const char*)Data, Size ); + std::istringstream ss( str ); + + elfio elf; + elf.load( ss ); + + return 0; +}