Skip to content

Commit 7d085ec

Browse files
bryanmcquadeknm3000
authored andcommitted
Bound maximum size of random_get buffer. (proxy-wasm#284)
Signed-off-by: Bryan McQuade <[email protected]>
1 parent 259d2cb commit 7d085ec

File tree

6 files changed

+128
-0
lines changed

6 files changed

+128
-0
lines changed

include/proxy-wasm/limits.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,10 @@
2323
#ifndef PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES
2424
#define PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES (1024 * 1024 * 1024)
2525
#endif
26+
27+
// Maximum allowed random_get buffer size. This value is consistent with
28+
// the JavaScript Crypto.getRandomValues() maximum buffer size.
29+
// See: https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues
30+
#ifndef PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES
31+
#define PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES (64 * 1024)
32+
#endif

src/exports.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515
//
16+
#include "include/proxy-wasm/limits.h"
1617
#include "include/proxy-wasm/wasm.h"
1718

1819
#include <openssl/rand.h>
@@ -884,6 +885,12 @@ Word wasi_unstable_clock_time_get(Word clock_id, uint64_t /*precision*/,
884885

885886
// __wasi_errno_t __wasi_random_get(uint8_t *buf, size_t buf_len);
886887
Word wasi_unstable_random_get(Word result_buf_ptr, Word buf_len) {
888+
if (buf_len > PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES) {
889+
return 28; // __WASI_EINVAL
890+
}
891+
if (buf_len == 0) {
892+
return 0; // __WASI_ESUCCESS
893+
}
887894
auto *context = contextOrEffectiveContext();
888895
std::vector<uint8_t> random(buf_len);
889896
RAND_bytes(random.data(), random.size());

test/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ cc_test(
7474
data = [
7575
"//test/test_data:clock.wasm",
7676
"//test/test_data:env.wasm",
77+
"//test/test_data:random.wasm",
7778
],
7879
linkstatic = 1,
80+
shard_count = 8,
7981
deps = [
8082
":utility_lib",
8183
"//:lib",

test/exports_test.cc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,73 @@ TEST_P(TestVm, Clock) {
8989
EXPECT_TRUE(context->isLogged("realtime: "));
9090
}
9191

92+
TEST_P(TestVm, RandomZero) {
93+
auto source = readTestWasmFile("random.wasm");
94+
ASSERT_FALSE(source.empty());
95+
auto wasm = TestWasm(std::move(vm_));
96+
ASSERT_TRUE(wasm.load(source, false));
97+
ASSERT_TRUE(wasm.initialize());
98+
99+
WasmCallVoid<1> run;
100+
wasm.wasm_vm()->getFunction("run", &run);
101+
ASSERT_TRUE(run != nullptr);
102+
run(wasm.vm_context(), Word{0});
103+
104+
// Check application logs.
105+
auto *context = dynamic_cast<TestContext *>(wasm.vm_context());
106+
EXPECT_TRUE(context->isLogged("random_get(0) succeeded."));
107+
}
108+
109+
TEST_P(TestVm, RandomSmall) {
110+
auto source = readTestWasmFile("random.wasm");
111+
ASSERT_FALSE(source.empty());
112+
auto wasm = TestWasm(std::move(vm_));
113+
ASSERT_TRUE(wasm.load(source, false));
114+
ASSERT_TRUE(wasm.initialize());
115+
116+
WasmCallVoid<1> run;
117+
wasm.wasm_vm()->getFunction("run", &run);
118+
ASSERT_TRUE(run != nullptr);
119+
run(wasm.vm_context(), Word{32});
120+
121+
// Check application logs.
122+
auto *context = dynamic_cast<TestContext *>(wasm.vm_context());
123+
EXPECT_TRUE(context->isLogged("random_get(32) succeeded."));
124+
}
125+
126+
TEST_P(TestVm, RandomLarge) {
127+
auto source = readTestWasmFile("random.wasm");
128+
ASSERT_FALSE(source.empty());
129+
auto wasm = TestWasm(std::move(vm_));
130+
ASSERT_TRUE(wasm.load(source, false));
131+
ASSERT_TRUE(wasm.initialize());
132+
133+
WasmCallVoid<1> run;
134+
wasm.wasm_vm()->getFunction("run", &run);
135+
ASSERT_TRUE(run != nullptr);
136+
run(wasm.vm_context(), Word{64 * 1024});
137+
138+
// Check application logs.
139+
auto *context = dynamic_cast<TestContext *>(wasm.vm_context());
140+
EXPECT_TRUE(context->isLogged("random_get(65536) succeeded."));
141+
}
142+
143+
TEST_P(TestVm, RandomTooLarge) {
144+
auto source = readTestWasmFile("random.wasm");
145+
ASSERT_FALSE(source.empty());
146+
auto wasm = TestWasm(std::move(vm_));
147+
ASSERT_TRUE(wasm.load(source, false));
148+
ASSERT_TRUE(wasm.initialize());
149+
150+
WasmCallVoid<1> run;
151+
wasm.wasm_vm()->getFunction("run", &run);
152+
ASSERT_TRUE(run != nullptr);
153+
run(wasm.vm_context(), Word{65 * 1024});
154+
155+
// Check application logs.
156+
auto *context = dynamic_cast<TestContext *>(wasm.vm_context());
157+
EXPECT_TRUE(context->isLogged("random_get(66560) failed."));
158+
}
159+
92160
} // namespace
93161
} // namespace proxy_wasm

test/test_data/BUILD

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,9 @@ wasm_rust_binary(
5353
srcs = ["clock.rs"],
5454
wasi = True,
5555
)
56+
57+
wasm_rust_binary(
58+
name = "random.wasm",
59+
srcs = ["random.rs"],
60+
wasi = True,
61+
)

test/test_data/random.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#[no_mangle]
16+
pub extern "C" fn proxy_abi_version_0_2_0() {}
17+
18+
#[no_mangle]
19+
pub extern "C" fn proxy_on_memory_allocate(_: usize) -> *mut u8 {
20+
std::ptr::null_mut()
21+
}
22+
23+
// TODO(PiotrSikora): switch to "getrandom" crate.
24+
pub mod wasi_snapshot_preview1 {
25+
#[link(wasm_import_module = "wasi_snapshot_preview1")]
26+
extern "C" {
27+
pub fn random_get(buf: *mut u8, buf_len: usize) -> u16;
28+
}
29+
}
30+
31+
#[no_mangle]
32+
pub extern "C" fn run(size: usize) {
33+
let mut buf: Vec<u8> = Vec::with_capacity(size);
34+
match unsafe { wasi_snapshot_preview1::random_get(buf.as_mut_ptr(), size) } {
35+
0 => println!("random_get({}) succeeded.", size),
36+
_ => println!("random_get({}) failed.", size),
37+
}
38+
}

0 commit comments

Comments
 (0)