[wasm] Enable wasm-gc for fuzzers

This will make our generic fuzzers (wasm-fuzzer, wasm-code-fuzzer,
wasm-async-fuzzer, ...) fuzz wasm-gc opcodes.
We were already fuzzing specific instructions in the wasm-compile
fuzzer, but were missing fuzzer coverage for corner cases and
instructions not supported by that fuzzer.

R=jkummerow@chromium.org
CC=manoskouk@chromium.org

Bug: v8:13496
Change-Id: Iccca96e32a64d20c11bc425fb5b1e9a1e3aa7486
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4030986
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84310}
This commit is contained in:
Clemens Backes 2022-11-16 18:01:23 +01:00 committed by V8 LUCI CQ
parent 0fa99183ef
commit 8de33e292e
6 changed files with 34 additions and 25 deletions

View File

@ -62,10 +62,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(support->GetContext());
// We explicitly enable staged WebAssembly features here to increase fuzzer
// coverage. For libfuzzer fuzzers it is not possible that the fuzzer enables
// the flag by itself.
OneTimeEnableStagedWasmFeatures(isolate);
// We explicitly enable staged/experimental WebAssembly features here to
// increase fuzzer coverage. For libfuzzer fuzzers it is not possible that the
// fuzzer enables the flag by itself.
EnableExperimentalWasmFeatures(isolate);
TryCatch try_catch(isolate);
testing::SetupIsolateForWasmModule(i_isolate);

View File

@ -2607,8 +2607,6 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
constexpr bool require_valid = true;
EXPERIMENTAL_FLAG_SCOPE(typed_funcref);
EXPERIMENTAL_FLAG_SCOPE(gc);
WasmCompileFuzzer().FuzzWasmModule({data, size}, require_valid);
return 0;
}

View File

@ -714,18 +714,29 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
}
}
void OneTimeEnableStagedWasmFeatures(v8::Isolate* isolate) {
struct EnableStagedWasmFeatures {
explicit EnableStagedWasmFeatures(v8::Isolate* isolate) {
#define ENABLE_STAGED_FEATURES(feat, desc, val) \
void EnableExperimentalWasmFeatures(v8::Isolate* isolate) {
struct EnableExperimentalWasmFeatures {
explicit EnableExperimentalWasmFeatures(v8::Isolate* isolate) {
// Enable all staged features.
#define ENABLE_STAGED_FEATURES(feat, ...) \
v8_flags.experimental_wasm_##feat = true;
FOREACH_WASM_STAGING_FEATURE_FLAG(ENABLE_STAGED_FEATURES)
#undef ENABLE_STAGED_FEATURES
// Enable non-staged experimental features that we also want to fuzz.
v8_flags.experimental_wasm_gc = true;
// Enforce implications from enabling features.
FlagList::EnforceFlagImplications();
// Last, install any conditional features. Implications are handled
// implicitly.
isolate->InstallConditionalFeatures(isolate->GetCurrentContext());
}
};
// The compiler will properly synchronize the constructor call.
static EnableStagedWasmFeatures one_time_enable_staged_features(isolate);
static EnableExperimentalWasmFeatures one_time_enable_experimental_features(
isolate);
}
void WasmExecutionFuzzer::FuzzWasmModule(base::Vector<const uint8_t> data,
@ -750,7 +761,7 @@ void WasmExecutionFuzzer::FuzzWasmModule(base::Vector<const uint8_t> data,
// We explicitly enable staged WebAssembly features here to increase fuzzer
// coverage. For libfuzzer fuzzers it is not possible that the fuzzer enables
// the flag by itself.
OneTimeEnableStagedWasmFeatures(isolate);
EnableExperimentalWasmFeatures(isolate);
v8::TryCatch try_catch(isolate);
HandleScope scope(i_isolate);

View File

@ -30,11 +30,11 @@ void InterpretAndExecuteModule(
void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
bool compiles);
// On the first call, enables all staged wasm features. All subsequent calls are
// no-ops. This avoids race conditions with threads reading the flags. Fuzzers
// are executed in their own process anyway, so this should not interfere with
// anything.
void OneTimeEnableStagedWasmFeatures(v8::Isolate* isolate);
// On the first call, enables all staged wasm features and experimental features
// that are ready for fuzzing. All subsequent calls are no-ops. This avoids race
// conditions with threads reading the flags. Fuzzers are executed in their own
// process anyway, so this should not interfere with anything.
void EnableExperimentalWasmFeatures(v8::Isolate* isolate);
class WasmExecutionFuzzer {
public:

View File

@ -151,10 +151,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(support->GetContext());
// We explicitly enable staged WebAssembly features here to increase fuzzer
// coverage. For libfuzzer fuzzers it is not possible that the fuzzer enables
// the flag by itself.
OneTimeEnableStagedWasmFeatures(isolate);
// We explicitly enable staged/experimental WebAssembly features here to
// increase fuzzer coverage. For libfuzzer fuzzers it is not possible that the
// fuzzer enables the flag by itself.
EnableExperimentalWasmFeatures(isolate);
// Limit the maximum module size to avoid OOM.
v8_flags.wasm_max_module_size = 256 * KB;

View File

@ -41,10 +41,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(support->GetContext());
// We explicitly enable staged WebAssembly features here to increase fuzzer
// coverage. For libfuzzer fuzzers it is not possible that the fuzzer enables
// the flag by itself.
OneTimeEnableStagedWasmFeatures(isolate);
// We explicitly enable staged/experimental WebAssembly features here to
// increase fuzzer coverage. For libfuzzer fuzzers it is not possible that the
// fuzzer enables the flag by itself.
EnableExperimentalWasmFeatures(isolate);
v8::TryCatch try_catch(isolate);
testing::SetupIsolateForWasmModule(i_isolate);