Skip to content

Commit

Permalink
Fix parsing EOF version in header (#957)
Browse files Browse the repository at this point in the history
Fixes the bug introduced in #947
where reading the version byte is missing the bounds check.

This bug is hard to detect when `std::string` is used as the test
container so the unit test framework has been modified to make it easier.

Found by a fuzzer.
  • Loading branch information
chfast authored Jul 24, 2024
2 parents 26d5609 + 1d357c2 commit 2ba35a0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/evmone/eof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ bool append_data_section(bytes& container, bytes_view aux_data)

uint8_t get_eof_version(bytes_view container) noexcept
{
return is_eof_container(container) ? container[2] : 0;
return (is_eof_container(container) && container.size() >= 3) ? container[2] : 0;
}

EOFValidationError validate_eof(
Expand Down
12 changes: 10 additions & 2 deletions test/unittests/eof_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,17 @@ void eof_validation::TearDown()
for (size_t i = 0; i < test_cases.size(); ++i)
{
const auto& test_case = test_cases[i];
EXPECT_EQ(evmone::validate_eof(rev, test_case.kind, test_case.container), test_case.error)

// Move the container to new heap-allocated buffer of exact size
// to easily find out-of-buffer reads with address sanitizer.
const auto size = test_case.container.size();
const auto buffer = std::make_unique_for_overwrite<uint8_t[]>(size);
std::ranges::copy(test_case.container, buffer.get());
const bytes_view container{buffer.get(), size};

EXPECT_EQ(evmone::validate_eof(rev, test_case.kind, container), test_case.error)
<< "test case " << i << " " << test_case.name << "\n"
<< hex(test_case.container);
<< hex(container);
}

if (!export_file_path.empty())
Expand Down

0 comments on commit 2ba35a0

Please sign in to comment.