From f55d2377850f31eba81eab884676b1c157d819c2 Mon Sep 17 00:00:00 2001 From: Bryan McQuade Date: Thu, 14 Apr 2022 20:47:34 -0400 Subject: [PATCH 1/8] Bound maximum size of random_git buffer. Signed-off-by: Bryan McQuade --- include/proxy-wasm/limits.h | 6 ++++++ src/exports.cc | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/include/proxy-wasm/limits.h b/include/proxy-wasm/limits.h index cb3e569e8..d5363cefd 100644 --- a/include/proxy-wasm/limits.h +++ b/include/proxy-wasm/limits.h @@ -23,3 +23,9 @@ #ifndef PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES #define PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES (1024 * 1024 * 1024) #endif + +// Maximum allowed random_get buffer size. This value is consistent with +// the JavaScript Crypto.getRandomValues() maximum buffer size. +#ifndef PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES +#define PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES (64 * 1024) +#endif diff --git a/src/exports.cc b/src/exports.cc index c203946b8..6b5f6872b 100644 --- a/src/exports.cc +++ b/src/exports.cc @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // +#include "include/proxy-wasm/limits.h" #include "include/proxy-wasm/wasm.h" #include @@ -884,6 +885,9 @@ Word wasi_unstable_clock_time_get(Word clock_id, uint64_t /*precision*/, // __wasi_errno_t __wasi_random_get(uint8_t *buf, size_t buf_len); Word wasi_unstable_random_get(Word result_buf_ptr, Word buf_len) { + if (buf_len > PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES) { + return 28; // __WASI_EINVAL + } auto *context = contextOrEffectiveContext(); std::vector random(buf_len); RAND_bytes(random.data(), random.size()); From fd5b29e91591c31cc6568d778fedcf970dee7515 Mon Sep 17 00:00:00 2001 From: bryanmcquade Date: Thu, 14 Apr 2022 20:58:27 -0400 Subject: [PATCH 2/8] Update limits.h Signed-off-by: Bryan McQuade --- include/proxy-wasm/limits.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/proxy-wasm/limits.h b/include/proxy-wasm/limits.h index d5363cefd..50918162d 100644 --- a/include/proxy-wasm/limits.h +++ b/include/proxy-wasm/limits.h @@ -25,7 +25,8 @@ #endif // Maximum allowed random_get buffer size. This value is consistent with -// the JavaScript Crypto.getRandomValues() maximum buffer size. +// the JavaScript Crypto.getRandomValues() maximum buffer size. See +// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#exceptions #ifndef PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES #define PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES (64 * 1024) #endif From 8b67bd81ef60980d952312f3d729fff93f059061 Mon Sep 17 00:00:00 2001 From: bryanmcquade Date: Thu, 14 Apr 2022 21:09:43 -0400 Subject: [PATCH 3/8] Update limits.h Updates Crypto.getRandomValues() link to point to the spec (canonical source). Signed-off-by: Bryan McQuade --- include/proxy-wasm/limits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/proxy-wasm/limits.h b/include/proxy-wasm/limits.h index 50918162d..4b1838c9b 100644 --- a/include/proxy-wasm/limits.h +++ b/include/proxy-wasm/limits.h @@ -26,7 +26,7 @@ // Maximum allowed random_get buffer size. This value is consistent with // the JavaScript Crypto.getRandomValues() maximum buffer size. See -// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#exceptions +// https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues #ifndef PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES #define PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES (64 * 1024) #endif From 1da3b2d17ee4b6c6aad808fa1230ce6b2e78b5c2 Mon Sep 17 00:00:00 2001 From: Bryan McQuade Date: Thu, 14 Apr 2022 21:20:19 -0400 Subject: [PATCH 4/8] Fix formatting Signed-off-by: Bryan McQuade --- src/exports.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exports.cc b/src/exports.cc index 6b5f6872b..bcecd2649 100644 --- a/src/exports.cc +++ b/src/exports.cc @@ -886,7 +886,7 @@ Word wasi_unstable_clock_time_get(Word clock_id, uint64_t /*precision*/, // __wasi_errno_t __wasi_random_get(uint8_t *buf, size_t buf_len); Word wasi_unstable_random_get(Word result_buf_ptr, Word buf_len) { if (buf_len > PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES) { - return 28; // __WASI_EINVAL + return 28; // __WASI_EINVAL } auto *context = contextOrEffectiveContext(); std::vector random(buf_len); From 466e4d9195d7985f1e94e418d75537fba566d518 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Fri, 15 Apr 2022 02:16:27 -0700 Subject: [PATCH 5/8] review: add tests. Signed-off-by: Piotr Sikora --- test/BUILD | 1 + test/exports_test.cc | 68 ++++++++++++++++++++++++++++++++++++++++ test/test_data/BUILD | 6 ++++ test/test_data/random.rs | 38 ++++++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 test/test_data/random.rs diff --git a/test/BUILD b/test/BUILD index 34481d83e..c59d27899 100644 --- a/test/BUILD +++ b/test/BUILD @@ -74,6 +74,7 @@ cc_test( data = [ "//test/test_data:clock.wasm", "//test/test_data:env.wasm", + "//test/test_data:random.wasm", ], linkstatic = 1, deps = [ diff --git a/test/exports_test.cc b/test/exports_test.cc index 40e0359d1..026019c03 100644 --- a/test/exports_test.cc +++ b/test/exports_test.cc @@ -89,5 +89,73 @@ TEST_P(TestVm, Clock) { EXPECT_TRUE(context->isLogged("realtime: ")); } +TEST_P(TestVm, RandomZero) { + auto source = readTestWasmFile("random.wasm"); + ASSERT_FALSE(source.empty()); + auto wasm = TestWasm(std::move(vm_)); + ASSERT_TRUE(wasm.load(source, false)); + ASSERT_TRUE(wasm.initialize()); + + WasmCallVoid<1> run; + wasm.wasm_vm()->getFunction("run", &run); + ASSERT_TRUE(run != nullptr); + run(wasm.vm_context(), Word{0}); + + // Check application logs. + auto *context = dynamic_cast(wasm.vm_context()); + EXPECT_TRUE(context->isLogged("random_get(0) succeeded.")); +} + +TEST_P(TestVm, RandomSmall) { + auto source = readTestWasmFile("random.wasm"); + ASSERT_FALSE(source.empty()); + auto wasm = TestWasm(std::move(vm_)); + ASSERT_TRUE(wasm.load(source, false)); + ASSERT_TRUE(wasm.initialize()); + + WasmCallVoid<1> run; + wasm.wasm_vm()->getFunction("run", &run); + ASSERT_TRUE(run != nullptr); + run(wasm.vm_context(), Word{32}); + + // Check application logs. + auto *context = dynamic_cast(wasm.vm_context()); + EXPECT_TRUE(context->isLogged("random_get(32) succeeded.")); +} + +TEST_P(TestVm, RandomLarge) { + auto source = readTestWasmFile("random.wasm"); + ASSERT_FALSE(source.empty()); + auto wasm = TestWasm(std::move(vm_)); + ASSERT_TRUE(wasm.load(source, false)); + ASSERT_TRUE(wasm.initialize()); + + WasmCallVoid<1> run; + wasm.wasm_vm()->getFunction("run", &run); + ASSERT_TRUE(run != nullptr); + run(wasm.vm_context(), Word{64 * 1024}); + + // Check application logs. + auto *context = dynamic_cast(wasm.vm_context()); + EXPECT_TRUE(context->isLogged("random_get(65536) succeeded.")); +} + +TEST_P(TestVm, RandomTooLarge) { + auto source = readTestWasmFile("random.wasm"); + ASSERT_FALSE(source.empty()); + auto wasm = TestWasm(std::move(vm_)); + ASSERT_TRUE(wasm.load(source, false)); + ASSERT_TRUE(wasm.initialize()); + + WasmCallVoid<1> run; + wasm.wasm_vm()->getFunction("run", &run); + ASSERT_TRUE(run != nullptr); + run(wasm.vm_context(), Word{65 * 1024}); + + // Check application logs. + auto *context = dynamic_cast(wasm.vm_context()); + EXPECT_TRUE(context->isLogged("random_get(66560) failed.")); +} + } // namespace } // namespace proxy_wasm diff --git a/test/test_data/BUILD b/test/test_data/BUILD index 3d09fa57e..553d43b14 100644 --- a/test/test_data/BUILD +++ b/test/test_data/BUILD @@ -53,3 +53,9 @@ wasm_rust_binary( srcs = ["clock.rs"], wasi = True, ) + +wasm_rust_binary( + name = "random.wasm", + srcs = ["random.rs"], + wasi = True, +) diff --git a/test/test_data/random.rs b/test/test_data/random.rs new file mode 100644 index 000000000..271434bb7 --- /dev/null +++ b/test/test_data/random.rs @@ -0,0 +1,38 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[no_mangle] +pub extern "C" fn proxy_abi_version_0_2_0() {} + +#[no_mangle] +pub extern "C" fn proxy_on_memory_allocate(_: usize) -> *mut u8 { + std::ptr::null_mut() +} + +// TODO(PiotrSikora): switch to "getrandom" crate. +pub mod wasi_snapshot_preview1 { + #[link(wasm_import_module = "wasi_snapshot_preview1")] + extern "C" { + pub fn random_get(buf: *mut u8, buf_len: usize) -> u16; + } +} + +#[no_mangle] +pub extern "C" fn run(size: usize) { + let mut buf: Vec = Vec::with_capacity(size); + match unsafe { wasi_snapshot_preview1::random_get(buf.as_mut_ptr(), size) } { + 0 => println!("random_get({}) succeeded.", size), + _ => println!("random_get({}) failed.", size), + } +} From fa20bc387946f751c884bdd9822741e1a8d6f498 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Fri, 15 Apr 2022 02:20:57 -0700 Subject: [PATCH 6/8] review: style. Signed-off-by: Piotr Sikora --- include/proxy-wasm/limits.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/proxy-wasm/limits.h b/include/proxy-wasm/limits.h index 4b1838c9b..d02d4c5e3 100644 --- a/include/proxy-wasm/limits.h +++ b/include/proxy-wasm/limits.h @@ -25,8 +25,8 @@ #endif // Maximum allowed random_get buffer size. This value is consistent with -// the JavaScript Crypto.getRandomValues() maximum buffer size. See -// https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues +// the JavaScript Crypto.getRandomValues() maximum buffer size. +// See: https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues #ifndef PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES #define PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES (64 * 1024) #endif From 5fc373960b8f5d10aba011bc78bed384c0dfdd72 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Fri, 15 Apr 2022 03:26:08 -0700 Subject: [PATCH 7/8] review: add fix for buf_len=0. Signed-off-by: Piotr Sikora --- src/exports.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/exports.cc b/src/exports.cc index bcecd2649..01aeb9623 100644 --- a/src/exports.cc +++ b/src/exports.cc @@ -888,6 +888,9 @@ Word wasi_unstable_random_get(Word result_buf_ptr, Word buf_len) { if (buf_len > PROXY_WASM_HOST_WASI_RANDOM_GET_MAX_SIZE_BYTES) { return 28; // __WASI_EINVAL } + if (buf_len == 0) { + return 0; // __WASI_ESUCCESS + } auto *context = contextOrEffectiveContext(); std::vector random(buf_len); RAND_bytes(random.data(), random.size()); From d90f41a73a14ebe84ee6490f78742648c5e19cc6 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Fri, 15 Apr 2022 12:30:22 -0700 Subject: [PATCH 8/8] review: shard tests to workaround test timeout on s390x. Signed-off-by: Piotr Sikora --- test/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/BUILD b/test/BUILD index c59d27899..93373486d 100644 --- a/test/BUILD +++ b/test/BUILD @@ -77,6 +77,7 @@ cc_test( "//test/test_data:random.wasm", ], linkstatic = 1, + shard_count = 8, deps = [ ":utility_lib", "//:lib",