From 1bde83046ebb8d4b1cfa2527a649a95af73ade50 Mon Sep 17 00:00:00 2001 From: ahaas Date: Mon, 14 Nov 2016 11:45:16 -0800 Subject: [PATCH] [wasm] Reimplement function verification in the module decoder. This CL adds the function verification option to the module decoder. Therefore we can remove the verification in wasm-module-runner.cc R=titzer@chromium.org Review-Url: https://codereview.chromium.org/2496203002 Cr-Commit-Position: refs/heads/master@{#40977} --- src/wasm/module-decoder.cc | 11 ++++++++++ src/wasm/wasm-module.cc | 2 +- test/common/wasm/wasm-module-runner.cc | 29 +++++--------------------- test/common/wasm/wasm-module-runner.h | 8 +++---- test/fuzzer/wasm-call.cc | 2 +- test/fuzzer/wasm-code.cc | 2 +- 6 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc index 272a60ddaa..c816fd3bd4 100644 --- a/src/wasm/module-decoder.cc +++ b/src/wasm/module-decoder.cc @@ -586,6 +586,14 @@ class ModuleDecoder : public Decoder { uint32_t size = consume_u32v("body size"); function->code_start_offset = pc_offset(); function->code_end_offset = pc_offset() + size; + if (verify_functions) { + ModuleEnv module_env; + module_env.module = module; + module_env.origin = module->origin; + + VerifyFunctionBody(i + module->num_imported_functions, &module_env, + function); + } consume_bytes(size, "function body"); } section_iter.advance(); @@ -646,6 +654,9 @@ class ModuleDecoder : public Decoder { } const WasmModule* finished_module = module; ModuleResult result = toResult(finished_module); + if (verify_functions && result.ok()) { + result.MoveFrom(result_); // Copy error code and location. + } if (FLAG_dump_wasm_module) DumpModule(module, result); return result; } diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc index 0b5ef15bc7..80e3700eff 100644 --- a/src/wasm/wasm-module.cc +++ b/src/wasm/wasm-module.cc @@ -1925,7 +1925,7 @@ MaybeHandle wasm::CreateModuleObjectFromBytes( bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, ModuleOrigin origin) { - ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); + ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin); if (result.val) { delete result.val; } else { diff --git a/test/common/wasm/wasm-module-runner.cc b/test/common/wasm/wasm-module-runner.cc index 225a887771..0b885175fc 100644 --- a/test/common/wasm/wasm-module-runner.cc +++ b/test/common/wasm/wasm-module-runner.cc @@ -24,15 +24,13 @@ uint32_t GetMinModuleMemSize(const WasmModule* module) { return WasmModule::kPageSize * module->min_mem_pages; } -const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, - ErrorThrower* thrower, - const byte* module_start, - const byte* module_end, - ModuleOrigin origin) { +const WasmModule* DecodeWasmModuleForTesting( + Isolate* isolate, ErrorThrower* thrower, const byte* module_start, + const byte* module_end, ModuleOrigin origin, bool verify_functions) { // Decode the module, but don't verify function bodies, since we'll // be compiling them anyway. - ModuleResult decoding_result = - DecodeWasmModule(isolate, module_start, module_end, false, origin); + ModuleResult decoding_result = DecodeWasmModule( + isolate, module_start, module_end, verify_functions, origin); if (decoding_result.failed()) { // Module verification failed. throw. @@ -129,22 +127,6 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, if (thrower->error()) return -1; - ModuleEnv module_env; - module_env.module = module; - module_env.origin = module->origin; - - for (size_t i = 0; i < module->functions.size(); i++) { - FunctionBody body = { - &module_env, module->functions[i].sig, module->module_start, - module->module_start + module->functions[i].code_start_offset, - module->module_start + module->functions[i].code_end_offset}; - DecodeResult result = VerifyWasmCode(isolate->allocator(), body); - if (result.failed()) { - thrower->CompileError("Function did not verify"); - return -1; - } - } - // The code verifies, we create an instance to run it in the interpreter. WasmInstance instance(module); instance.context = isolate->native_context(); @@ -154,7 +136,6 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, instance.mem_start = static_cast(calloc(GetMinModuleMemSize(module), 1)); instance.globals_start = nullptr; - module_env.instance = &instance; WasmInterpreter interpreter(&instance, isolate->allocator()); diff --git a/test/common/wasm/wasm-module-runner.h b/test/common/wasm/wasm-module-runner.h index 3c597b3330..d6702e1e37 100644 --- a/test/common/wasm/wasm-module-runner.h +++ b/test/common/wasm/wasm-module-runner.h @@ -19,11 +19,9 @@ namespace wasm { namespace testing { // Decodes the given encoded module. -const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, - ErrorThrower* thrower, - const byte* module_start, - const byte* module_end, - ModuleOrigin origin); +const WasmModule* DecodeWasmModuleForTesting( + Isolate* isolate, ErrorThrower* thrower, const byte* module_start, + const byte* module_end, ModuleOrigin origin, bool verify_functions = false); // Instantiates a module without any imports and exports. const Handle InstantiateModuleForTesting(Isolate* isolate, diff --git a/test/fuzzer/wasm-call.cc b/test/fuzzer/wasm-call.cc index ffc4637c8a..fb9a696135 100644 --- a/test/fuzzer/wasm-call.cc +++ b/test/fuzzer/wasm-call.cc @@ -136,7 +136,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ErrorThrower interpreter_thrower(i_isolate, "Interpreter"); std::unique_ptr module(testing::DecodeWasmModuleForTesting( i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(), - v8::internal::wasm::ModuleOrigin::kWasmOrigin)); + v8::internal::wasm::ModuleOrigin::kWasmOrigin, true)); if (module == nullptr) { return 0; diff --git a/test/fuzzer/wasm-code.cc b/test/fuzzer/wasm-code.cc index 49411c3f41..3f7b091883 100644 --- a/test/fuzzer/wasm-code.cc +++ b/test/fuzzer/wasm-code.cc @@ -57,7 +57,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ErrorThrower interpreter_thrower(i_isolate, "Interpreter"); std::unique_ptr module(testing::DecodeWasmModuleForTesting( i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(), - v8::internal::wasm::ModuleOrigin::kWasmOrigin)); + v8::internal::wasm::ModuleOrigin::kWasmOrigin, true)); if (module == nullptr) { return 0;