Skip to content

Commit

Permalink
Validate that all used instructions are defined and pushdata is complete
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Oct 4, 2021
1 parent 94a7518 commit c350486
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 159 deletions.
40 changes: 35 additions & 5 deletions lib/evmone/eof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
// SPDX-License-Identifier: Apache-2.0

#include "eof.hpp"
#include "instruction_traits.hpp"

#include <array>
#include <cassert>
#include <limits>

namespace evmone
{
Expand Down Expand Up @@ -99,6 +101,28 @@ std::pair<EOFSectionHeaders, EOFValidationErrror> validate_eof_headers(
return {section_headers, EOFValidationErrror::success};
}

EOFValidationErrror validate_instructions(
evmc_revision rev, const uint8_t* code, size_t code_size) noexcept
{
// const auto* names = instr::traits[op].since;

size_t i = 0;
while (i < code_size)
{
const auto op = code[i];
const auto& since = instr::traits[op].since;
if (!since.has_value() || *since > rev)
return EOFValidationErrror::undefined_instruction;

i += instr::traits[op].immediate_size;
++i;
}
if (i != code_size)
return EOFValidationErrror::truncated_immediate;

return EOFValidationErrror::success;
}

} // namespace

size_t EOF1Header::code_begin() const noexcept
Expand Down Expand Up @@ -135,13 +159,19 @@ uint8_t get_eof_version(const uint8_t* code, size_t code_size) noexcept
}

std::pair<EOF1Header, EOFValidationErrror> validate_eof1(
const uint8_t* code, size_t code_size) noexcept
evmc_revision rev, const uint8_t* code, size_t code_size) noexcept
{
const auto [section_headers, error] = validate_eof_headers(code, code_size);
if (error != EOFValidationErrror::success)
return {{}, error};
const auto [section_headers, error_header] = validate_eof_headers(code, code_size);
if (error_header != EOFValidationErrror::success)
return {{}, error_header};

EOF1Header header{section_headers[CODE_SECTION], section_headers[DATA_SECTION]};

const auto error_instr =
validate_instructions(rev, &code[header.code_begin()], header.code_size);
if (error_instr != EOFValidationErrror::success)
return {{}, error_instr};

return {header, EOFValidationErrror::success};
}

Expand All @@ -160,7 +190,7 @@ EOFValidationErrror validate_eof(evmc_revision rev, const uint8_t* code, size_t
{
if (rev < EVMC_SHANGHAI)
return EOFValidationErrror::eof_version_unknown;
return validate_eof1(code, code_size).second;
return validate_eof1(rev, code, code_size).second;
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion lib/evmone/eof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ enum class EOFValidationErrror
zero_section_size,
section_headers_not_terminated,
invalid_section_bodies_size,
undefined_instruction,
truncated_immediate,

initcode_failure,
impossible,
Expand All @@ -52,7 +54,7 @@ enum class EOFValidationErrror
uint8_t get_eof_version(const uint8_t* code, size_t code_size) noexcept;

std::pair<EOF1Header, EOFValidationErrror> validate_eof1(
const uint8_t* code, size_t code_size) noexcept;
evmc_revision rev, const uint8_t* code, size_t code_size) noexcept;

EVMC_EXPORT EOFValidationErrror validate_eof(
evmc_revision rev, const uint8_t* code, size_t code_size) noexcept;
Expand Down
Loading

0 comments on commit c350486

Please sign in to comment.