Skip to content

Commit 61135c5

Browse files
authored
v8: set upper limit for maximum Wasm memory size. (#281)
Signed-off-by: Piotr Sikora <[email protected]>
1 parent eba773f commit 61135c5

File tree

7 files changed

+76
-4
lines changed

7 files changed

+76
-4
lines changed

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ filegroup(
2323
cc_library(
2424
name = "wasm_vm_headers",
2525
hdrs = [
26+
"include/proxy-wasm/limits.h",
2627
"include/proxy-wasm/wasm_vm.h",
2728
"include/proxy-wasm/word.h",
2829
],

include/proxy-wasm/limits.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
// Wasm memory page is always 64 KiB.
20+
#define PROXY_WASM_HOST_WASM_MEMORY_PAGE_SIZE_BYTES (64 * 1024)
21+
22+
// Maximum allowed Wasm memory size.
23+
#ifndef PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES
24+
#define PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES (1024 * 1024 * 1024)
25+
#endif

src/v8/v8.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@
2626
#include <utility>
2727
#include <vector>
2828

29+
#include "include/proxy-wasm/limits.h"
30+
2931
#include "include/v8-version.h"
3032
#include "include/v8.h"
3133
#include "src/wasm/c-api.h"
3234
#include "wasm-api/wasm.hh"
3335

36+
namespace v8::internal {
37+
extern unsigned int FLAG_wasm_max_mem_pages;
38+
} // namespace v8::internal
39+
3440
namespace proxy_wasm {
3541
namespace v8 {
3642

@@ -39,6 +45,8 @@ wasm::Engine *engine() {
3945
static wasm::own<wasm::Engine> engine;
4046

4147
std::call_once(init, []() {
48+
::v8::internal::FLAG_wasm_max_mem_pages =
49+
PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES / PROXY_WASM_HOST_WASM_MEMORY_PAGE_SIZE_BYTES;
4250
::v8::V8::EnableWebAssemblyTrapHandler(true);
4351
engine = wasm::Engine::make();
4452
});

test/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ cc_test(
5656
data = [
5757
"//test/test_data:callback.wasm",
5858
"//test/test_data:clock.wasm",
59-
"//test/test_data:infinite_loop.wasm",
59+
"//test/test_data:resource_limits.wasm",
6060
"//test/test_data:trap.wasm",
6161
],
6262
linkstatic = 1,

test/runtime_test.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <thread>
2020

2121
#include "include/proxy-wasm/context.h"
22+
#include "include/proxy-wasm/limits.h"
2223
#include "include/proxy-wasm/wasm.h"
2324

2425
#include "test/utility.h"
@@ -86,7 +87,7 @@ TEST_P(TestVm, TerminateExecution) {
8687
if (engine_ != "v8") {
8788
return;
8889
}
89-
auto source = readTestWasmFile("infinite_loop.wasm");
90+
auto source = readTestWasmFile("resource_limits.wasm");
9091
ASSERT_FALSE(source.empty());
9192
auto wasm = TestWasm(std::move(vm_));
9293
ASSERT_TRUE(wasm.load(source, false));
@@ -112,6 +113,35 @@ TEST_P(TestVm, TerminateExecution) {
112113
}
113114
}
114115

116+
TEST_P(TestVm, WasmMemoryLimit) {
117+
// TODO(PiotrSikora): enforce memory limits in other engines.
118+
if (engine_ != "v8") {
119+
return;
120+
}
121+
auto source = readTestWasmFile("resource_limits.wasm");
122+
ASSERT_FALSE(source.empty());
123+
auto wasm = TestWasm(std::move(vm_));
124+
ASSERT_TRUE(wasm.load(source, false));
125+
ASSERT_TRUE(wasm.initialize());
126+
127+
WasmCallVoid<0> infinite_memory;
128+
wasm.wasm_vm()->getFunction("infinite_memory", &infinite_memory);
129+
ASSERT_TRUE(infinite_memory != nullptr);
130+
infinite_memory(wasm.vm_context());
131+
132+
EXPECT_GE(wasm.wasm_vm()->getMemorySize(), PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES * 0.95);
133+
EXPECT_LE(wasm.wasm_vm()->getMemorySize(), PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES);
134+
135+
// Check integration logs.
136+
auto *host = dynamic_cast<TestIntegration *>(wasm.wasm_vm()->integration().get());
137+
EXPECT_TRUE(host->isErrorLogged("Function: infinite_memory failed"));
138+
if (engine_ == "v8") {
139+
EXPECT_TRUE(host->isErrorLogged("Uncaught RuntimeError: unreachable"));
140+
EXPECT_TRUE(host->isErrorLogged("Proxy-Wasm plugin in-VM backtrace:"));
141+
EXPECT_TRUE(host->isErrorLogged(" - rust_oom"));
142+
}
143+
}
144+
115145
TEST_P(TestVm, Trap) {
116146
auto source = readTestWasmFile("trap.wasm");
117147
ASSERT_FALSE(source.empty());

test/test_data/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ wasm_rust_binary(
3838
)
3939

4040
wasm_rust_binary(
41-
name = "infinite_loop.wasm",
42-
srcs = ["infinite_loop.rs"],
41+
name = "resource_limits.wasm",
42+
srcs = ["resource_limits.rs"],
4343
)
4444

4545
wasm_rust_binary(

test/test_data/infinite_loop.rs renamed to test/test_data/resource_limits.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ pub extern "C" fn infinite_loop() {
2727
_count += 1;
2828
}
2929
}
30+
31+
#[no_mangle]
32+
pub extern "C" fn infinite_memory() {
33+
let mut vec = Vec::new();
34+
loop {
35+
vec.push(Vec::<u32>::with_capacity(16384));
36+
}
37+
}

0 commit comments

Comments
 (0)