Check out of the file boundary access attemps

This commit is contained in:
Serge Lamikhov-Center 2022-06-16 17:30:22 +03:00
parent 38d61e30a7
commit 07ef317550
5 changed files with 47 additions and 9 deletions

14
.vscode/launch.json vendored
View File

@ -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",
}
]
}

View File

@ -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;
}

View File

@ -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 T> 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<char*>( &header ), sizeof( header ),
'\0' );
@ -226,6 +226,11 @@ template <class T> 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 T> class section_impl : public section
data_size = 0;
}
}
return true;
}
//------------------------------------------------------------------------------

View File

@ -61,7 +61,7 @@ class segment
ELFIO_SET_ACCESS_DECL( Elf_Half, index );
virtual const std::vector<Elf_Half>& 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 T> 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 T> 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;
}
//------------------------------------------------------------------------------

16
tests/elfio_fuzzer.cpp Normal file
View File

@ -0,0 +1,16 @@
#include <string>
#include <sstream>
#include <elfio/elfio.hpp>
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;
}