Skip to content

Commit

Permalink
precompiles: Improve output buffer handling
Browse files Browse the repository at this point in the history
Replace the fixed-size on-stack temporary buffer for precompiles
with a heap-allocated buffer big enough to handle properly any
precompile invocation.

This actually keeps the number of allocations the same. Previously
the contents of the on-stack buffer were copied to heap
by the Result constructor. Now we are creating the heap buffer
in the first place and pass the ownership of it to the Result.

This fixes out-of-bounds memory accesses often being found by fuzzers.
  • Loading branch information
chfast committed Jul 11, 2024
1 parent 8e2e110 commit c5c79e6
Showing 1 changed file with 5 additions and 13 deletions.
18 changes: 5 additions & 13 deletions test/state/precompiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,19 +364,11 @@ evmc::Result call_precompile(evmc_revision rev, const evmc_message& msg) noexcep
if (gas_left < 0)
return evmc::Result{EVMC_OUT_OF_GAS};

// Buffer for the precompile's output.
// Big enough to handle all "expmod" tests, but in case does not match the size requirement
// from analysis, the result will likely be incorrect.
// TODO: Replace with std::pmr::monotonic_buffer_resource?
uint8_t output_buf[4096];
assert(std::size(output_buf) >= max_output_size);

const auto output_buf = new uint8_t[max_output_size];

Check warning on line 367 in test/state/precompiles.cpp

View check run for this annotation

Codecov / codecov/patch

test/state/precompiles.cpp#L367

Added line #L367 was not covered by tests
const auto [status_code, output_size] =
execute(msg.input_data, msg.input_size, output_buf, std::size(output_buf));

evmc::Result result{
status_code, status_code == EVMC_SUCCESS ? gas_left : 0, 0, output_buf, output_size};

return result;
execute(msg.input_data, msg.input_size, output_buf, max_output_size);
evmc_result result{status_code, status_code == EVMC_SUCCESS ? gas_left : 0, 0, output_buf,
output_size, [](const evmc_result* res) noexcept { delete[] res->output_data; }};
return evmc::Result{result};

Check warning on line 372 in test/state/precompiles.cpp

View check run for this annotation

Codecov / codecov/patch

test/state/precompiles.cpp#L369-L372

Added lines #L369 - L372 were not covered by tests
}
} // namespace evmone::state

0 comments on commit c5c79e6

Please sign in to comment.