From 661ae32122f9f0ba70b03b2d76a41274ce5e4bb2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 16 Mar 2021 12:01:26 -0700 Subject: Validate code in global data structures (#3694) This validation is almost never needed, but it starts to get interesting with GC, where a global initializer can be an rtt.sub which must be valid. No tests here as testing requires a further GC fix in a later PR. --- src/wasm/wasm-validator.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/wasm/wasm-validator.cpp') diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 80b7eb874..a057f34b9 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -201,13 +201,21 @@ struct ValidationInfo { struct FunctionValidator : public WalkerPass> { bool isFunctionParallel() override { return true; } - Pass* create() override { return new FunctionValidator(&info); } + Pass* create() override { return new FunctionValidator(*getModule(), &info); } bool modifiesBinaryenIR() override { return false; } ValidationInfo& info; - FunctionValidator(ValidationInfo* info) : info(*info) {} + FunctionValidator(Module& wasm, ValidationInfo* info) : info(*info) { + setModule(&wasm); + } + + // Validate the entire module. + void validate(PassRunner* runner) { run(runner, getModule()); } + + // Validate a specific expression. + void validate(Expression* curr) { walk(curr); } std::unordered_map> breakTypes; std::unordered_set delegateTargetNames; @@ -2710,6 +2718,7 @@ static void validateGlobals(Module& module, ValidationInfo& info) { !info.quiet) { info.getStream(nullptr) << "(on global " << curr->name << ")\n"; } + FunctionValidator(module, &info).validate(curr->init); }); } @@ -2775,6 +2784,7 @@ static void validateMemory(Module& module, ValidationInfo& info) { segment.data.size(), "segment size should fit in memory (end)"); } + FunctionValidator(module, &info).validate(segment.offset); } // If the memory is imported we don't actually know its initial size. // Specifically wasm dll's import a zero sized memory which is perfectly @@ -2809,6 +2819,7 @@ static void validateTables(Module& module, ValidationInfo& info) { table->initial * Table::kPageSize), segment->offset, "table segment offset should be reasonable"); + FunctionValidator(module, &info).validate(segment->offset); } for (auto name : segment->data) { info.shouldBeTrue( @@ -2879,7 +2890,7 @@ bool WasmValidator::validate(Module& module, Flags flags) { info.quiet = (flags & Quiet) != 0; // parallel wasm logic validation PassRunner runner(&module); - FunctionValidator(&info).run(&runner, &module); + FunctionValidator(module, &info).validate(&runner); // validate globally if (info.validateGlobally) { validateImports(module, info); -- cgit v1.2.3