Skip to content

Commit

Permalink
Undefine RJUMP* instructions in non-EOF code
Browse files Browse the repository at this point in the history
Co-authored-by: Paweł Bylica <pawel@hepcolgum.band>
  • Loading branch information
gumb0 and chfast committed Dec 6, 2022
1 parent 05ac15b commit 1ab5b19
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 17 deletions.
6 changes: 4 additions & 2 deletions lib/evmone/baseline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ CodeAnalysis analyze_legacy(bytes_view code)
CodeAnalysis analyze_eof1(bytes_view eof_container, const EOF1Header& header)
{
const auto executable_code = eof_container.substr(header.code_begin(), header.code_size);
return {executable_code.data(), analyze_jumpdests(executable_code)};

// FIXME: Better way of getting EOF version.
return {executable_code.data(), analyze_jumpdests(executable_code), eof_container[2]};
}
} // namespace

Expand Down Expand Up @@ -321,7 +323,7 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana

const auto code = analysis.executable_code;

const auto& cost_table = get_baseline_cost_table(state.rev);
const auto& cost_table = get_baseline_cost_table(state.rev, analysis.eof_version);

auto* tracer = vm.get_tracer();
if (INTX_UNLIKELY(tracer != nullptr))
Expand Down
5 changes: 3 additions & 2 deletions lib/evmone/baseline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class CodeAnalysis

const uint8_t* executable_code; ///< Pointer to the beginning of executable code section.
JumpdestMap jumpdest_map; ///< Map of valid jump destinations.
uint8_t eof_version = 0; ///< The EOF version, 0 means legacy code.

private:
/// Padded code for faster legacy code execution.
Expand All @@ -38,8 +39,8 @@ class CodeAnalysis
m_padded_code{std::move(padded_code)}
{}

CodeAnalysis(const uint8_t* code, JumpdestMap map)
: executable_code{code}, jumpdest_map{std::move(map)}
CodeAnalysis(const uint8_t* code, JumpdestMap map, uint8_t eof_ver)
: executable_code{code}, jumpdest_map{std::move(map)}, eof_version{eof_ver}
{}
};
static_assert(std::is_move_constructible_v<CodeAnalysis>);
Expand Down
36 changes: 24 additions & 12 deletions lib/evmone/baseline_instruction_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,33 @@

namespace evmone::baseline
{
const CostTable& get_baseline_cost_table(evmc_revision rev) noexcept
namespace
{
static constexpr auto cost_tables = []() noexcept {
std::array<CostTable, EVMC_MAX_REVISION + 1> tables{};
for (size_t r = EVMC_FRONTIER; r <= EVMC_MAX_REVISION; ++r)
constexpr auto eof_cost_tables = []() noexcept {
std::array<CostTable, EVMC_MAX_REVISION + 1> tables{};
for (size_t r = EVMC_FRONTIER; r <= EVMC_MAX_REVISION; ++r)
{
auto& table = tables[r];
for (size_t i = 0; i < table.size(); ++i)
{
auto& table = tables[r];
for (size_t i = 0; i < table.size(); ++i)
{
table[i] = instr::gas_costs[r][i]; // Include instr::undefined in the table.
}
table[i] = instr::gas_costs[r][i]; // Include instr::undefined in the table.
}
return tables;
}();
}
return tables;
}();

return cost_tables[rev];
constexpr auto legacy_cost_tables = []() noexcept {
auto tables = eof_cost_tables;
tables[EVMC_SHANGHAI][OP_RJUMP] = instr::undefined;
tables[EVMC_SHANGHAI][OP_RJUMPI] = instr::undefined;
return tables;
}();

} // namespace

const CostTable& get_baseline_cost_table(evmc_revision rev, uint8_t eof_version) noexcept
{
const auto& tables = (eof_version == 0) ? legacy_cost_tables : eof_cost_tables;
return tables[rev];
}
} // namespace evmone::baseline
4 changes: 3 additions & 1 deletion lib/evmone/baseline_instruction_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ namespace evmone::baseline
{
using CostTable = std::array<int16_t, 256>;

const CostTable& get_baseline_cost_table(evmc_revision rev) noexcept;
const CostTable& get_baseline_cost_table(evmc_revision rev, uint8_t eof_version) noexcept;

const CostTable& get_baseline_legacy_cost_table(evmc_revision rev) noexcept;
} // namespace evmone::baseline
15 changes: 15 additions & 0 deletions test/unittests/evm_eof_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,18 @@ TEST_P(evm, eof2_rjumpi_0_offset)
ASSERT_EQ(result.output_size, 1);
EXPECT_EQ(result.output_data[0], 1);
}


TEST_P(evm, relative_jumps_undefined_in_legacy)
{
rev = EVMC_SHANGHAI;
auto code = rjump(1) + OP_INVALID + mstore8(0, 1) + ret(0, 1);

execute(code);
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);

code = rjumpi(10, 1) + mstore8(0, 2) + ret(0, 1) + mstore8(0, 1) + ret(0, 1);

execute(code);
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);
}

0 comments on commit 1ab5b19

Please sign in to comment.