Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

unit test ensuring that OOB table init allowed on set code; fails on action #7736

Merged
merged 3 commits into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions libraries/chain/webassembly/wavm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,17 @@ std::unique_ptr<wasm_instantiated_module_interface> wavm_runtime::instantiate_mo
EOS_ASSERT(false, wasm_serialization_error, e.message.c_str());
}

eosio::chain::webassembly::common::root_resolver resolver;
LinkResult link_result = linkModule(*module, resolver);
ModuleInstance *instance = instantiateModule(*module, std::move(link_result.resolvedImports));
EOS_ASSERT(instance != nullptr, wasm_exception, "Fail to Instantiate WAVM Module");
try {
eosio::chain::webassembly::common::root_resolver resolver;
LinkResult link_result = linkModule(*module, resolver);
ModuleInstance *instance = instantiateModule(*module, std::move(link_result.resolvedImports));
EOS_ASSERT(instance != nullptr, wasm_exception, "Fail to Instantiate WAVM Module");

return std::make_unique<wavm_instantiated_module>(instance, std::move(module), initial_memory);
return std::make_unique<wavm_instantiated_module>(instance, std::move(module), initial_memory);
}
catch(const Runtime::Exception& e) {
EOS_THROW(wasm_execution_error, "Failed to stand up WAVM instance: ${m}", ("m", describeExceptionCause(e.cause)));
}
}

void wavm_runtime::immediately_exit_currently_running_module() {
Expand Down
32 changes: 32 additions & 0 deletions unittests/contracts/test_wasts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,38 @@ static const char table_checker_small_wast[] = R"=====(
)
)=====";

static const char table_init_oob_wast[] = R"=====(
(module
(type $mahsig (func (param i64) (param i64) (param i64)))
(table 1024 anyfunc)
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
)
(elem (i32.const 1024) $apply)
)
)=====";

static const char table_init_oob_smaller_wast[] = R"=====(
(module
(type $mahsig (func (param i64) (param i64) (param i64)))
(table 620 anyfunc)
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
)
(elem (i32.const 700) $apply)
)
)=====";

static const char table_init_oob_no_table_wast[] = R"=====(
(module
(type $mahsig (func (param i64) (param i64) (param i64)))
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
)
(elem (i32.const 0) $apply)
)
)=====";

static const char global_protection_none_get_wast[] = R"=====(
(module
(export "apply" (func $apply))
Expand Down
36 changes: 36 additions & 0 deletions unittests/wasm_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,42 @@ BOOST_FIXTURE_TEST_CASE( table_init_tests, TESTER ) try {

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( table_init_oob, TESTER ) try {
create_accounts( {N(tableinitoob)} );
produce_block();

signed_transaction trx;
trx.actions.emplace_back(vector<permission_level>{{N(tableinitoob),config::active_name}}, N(tableinitoob), N(), bytes{});
trx.actions[0].authorization = vector<permission_level>{{N(tableinitoob),config::active_name}};

auto pushit_and_expect_fail = [&]() {
produce_block();
trx.signatures.clear();
set_transaction_headers(trx);
trx.sign(get_private_key(N(tableinitoob), "active"), control->get_chain_id());

//the unspecified_exception_code comes from WAVM, which manages to throw a WAVM specific exception
// up to where exec_one captures it and doesn't understand it
b1bart marked this conversation as resolved.
Show resolved Hide resolved
BOOST_CHECK_THROW(push_transaction(trx), eosio::chain::wasm_execution_error);
};

set_code(N(tableinitoob), table_init_oob_wast);
produce_block();

pushit_and_expect_fail();
//make sure doing it again didn't lodge something funky in to a cache
pushit_and_expect_fail();

set_code(N(tableinitoob), table_init_oob_smaller_wast);
produce_block();
pushit_and_expect_fail();
pushit_and_expect_fail();

//an elem w/o a table is a setcode fail though
BOOST_CHECK_THROW(set_code(N(tableinitoob), table_init_oob_no_table_wast), eosio::chain::wasm_exception);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( memory_init_border, TESTER ) try {
produce_blocks(2);

Expand Down