Skip to content

Commit 28c9603

Browse files
committed
Implement execution limits for wasmtime
Implements execution termination (with [wasmtime epochs](https://docs.wasmtime.dev/examples-interrupting-wasm.html)) as well as memory limits. Signed-off-by: Matt Leon <mattleon@google.com>
1 parent c0fe685 commit 28c9603

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

src/wasmtime/wasmtime.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <cassert>
1818
#include <cstring>
19+
#include <limits>
1920
#include <memory>
2021
#include <optional>
2122
#include <string>
@@ -56,7 +57,11 @@ using ::wasmtime::Table;
5657
using ::wasmtime::TrapResult;
5758

5859
Engine *engine() {
59-
static auto *const engine = []() { return new Engine(Config{}); }();
60+
static auto *const engine = []() {
61+
Config config;
62+
config.epoch_interruption(true);
63+
return new Engine(std::move(config));
64+
}();
6065
return engine;
6166
}
6267

@@ -121,7 +126,7 @@ class Wasmtime : public WasmVm {
121126

122127
void warm() override;
123128

124-
void terminate() override {}
129+
void terminate() override { engine()->increment_epoch(); }
125130

126131
bool usesWasmByteOrder() override { return true; }
127132

@@ -160,6 +165,11 @@ void Wasmtime::initStore() {
160165
return;
161166
}
162167
store_.emplace(*engine());
168+
store_->limiter(PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES,
169+
/*table_elements=*/std::numeric_limits<int64_t>::max(),
170+
/*instances=*/std::numeric_limits<int64_t>::max(),
171+
/*tables=*/std::numeric_limits<int64_t>::max(),
172+
/*memories=*/std::numeric_limits<int64_t>::max());
163173
}
164174

165175
bool Wasmtime::load(std::string_view bytecode, std::string_view /*precompiled*/,
@@ -354,6 +364,7 @@ void Wasmtime::getModuleFunctionImpl(std::string_view function_name,
354364
")");
355365
}
356366
InPlaceConvertHostToWasmEndianness(args...);
367+
store_->context().set_epoch_deadline(1);
357368
TrapResult<std::monostate> result = func.call(store_->context(), {args...});
358369
if (!result) {
359370
fail(FailState::RuntimeError,
@@ -387,6 +398,7 @@ void Wasmtime::getModuleFunctionImpl(std::string_view function_name,
387398
")");
388399
}
389400
InPlaceConvertHostToWasmEndianness(args...);
401+
store_->context().set_epoch_deadline(1);
390402
TrapResult<R> result_wasm = func.call(store_->context(), {args...});
391403
if (!result_wasm) {
392404
fail(FailState::RuntimeError,

test/runtime_test.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ TEST_P(TestVm, StraceLogLevel) {
7878

7979
TEST_P(TestVm, TerminateExecution) {
8080
// TODO(chaoqin-li1123): implement execution termination for other runtime.
81-
if (engine_ != "v8") {
81+
if (engine_ != "v8" && engine_ != "wasmtime") {
8282
return;
8383
}
8484
auto source = readTestWasmFile("resource_limits.wasm");
@@ -102,12 +102,16 @@ TEST_P(TestVm, TerminateExecution) {
102102
// Check integration logs.
103103
auto *host = dynamic_cast<TestIntegration *>(wasm.wasm_vm()->integration().get());
104104
EXPECT_TRUE(host->isErrorLogged("Function: infinite_loop failed"));
105-
EXPECT_TRUE(host->isErrorLogged("TerminationException"));
105+
if (engine_ == "v8") {
106+
EXPECT_TRUE(host->isErrorLogged("TerminationException"));
107+
} else if (engine_ == "wasmtime") {
108+
EXPECT_TRUE(host->isErrorLogged("wasm trap: interrupt"));
109+
}
106110
}
107111

108112
TEST_P(TestVm, WasmMemoryLimit) {
109113
// TODO(PiotrSikora): enforce memory limits in other engines.
110-
if (engine_ != "v8") {
114+
if (engine_ != "v8" && engine_ != "wasmtime") {
111115
return;
112116
}
113117
auto source = readTestWasmFile("resource_limits.wasm");

0 commit comments

Comments
 (0)