Commit a024ea4b authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm][fuzzer] Fix data race when setting flags

Fuzzers are executed in their own process, so instead of resetting flags
after execution, we can just keep the flag values.
This CL introduces a shared function to enable all staged features,
without ever resetting the value. This fixes a data race.

R=ahaas@chromium.org

Bug: v8:10979
Change-Id: I82ea35b887841850edd8b394a3644cf8df1e3bf8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2449969
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70320}
parent 77cc96aa
......@@ -48,17 +48,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// 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.
#define ENABLE_STAGED_FEATURES(feat, desc, val) \
i::FlagScope<bool> enable_##feat(&i::FLAG_experimental_wasm_##feat, true);
FOREACH_WASM_STAGING_FEATURE_FLAG(ENABLE_STAGED_FEATURES)
#undef ENABLE_STAGED_FEATURES
FlagScope<bool> turn_on_async_compile(
&v8::internal::FLAG_wasm_async_compilation, true);
FlagScope<uint32_t> max_mem_flag_scope(&v8::internal::FLAG_wasm_max_mem_pages,
32);
FlagScope<uint32_t> max_table_size_scope(
&v8::internal::FLAG_wasm_max_table_size, 100);
OneTimeEnableStagedWasmFeatures();
// Set some more flags.
FLAG_wasm_async_compilation = true;
FLAG_wasm_max_mem_pages = 32;
FLAG_wasm_max_table_size = 100;
v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
v8::Isolate* isolate = support->GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<v8::internal::Isolate*>(isolate);
......
......@@ -305,15 +305,25 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
}
}
void OneTimeEnableStagedWasmFeatures() {
struct EnableStagedWasmFeatures {
EnableStagedWasmFeatures() {
#define ENABLE_STAGED_FEATURES(feat, desc, val) \
FLAG_experimental_wasm_##feat = true;
FOREACH_WASM_STAGING_FEATURE_FLAG(ENABLE_STAGED_FEATURES)
#undef ENABLE_STAGED_FEATURES
}
};
// The compiler will properly synchronize the constructor call.
static EnableStagedWasmFeatures one_time_enable_staged_features;
}
void WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
bool require_valid) {
// 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.
#define ENABLE_STAGED_FEATURES(feat, desc, val) \
FlagScope<bool> enable_##feat(&FLAG_experimental_wasm_##feat, true);
FOREACH_WASM_STAGING_FEATURE_FLAG(ENABLE_STAGED_FEATURES)
#undef ENABLE_STAGED_FEATURES
OneTimeEnableStagedWasmFeatures();
// Strictly enforce the input size limit. Note that setting "max_len" on the
// fuzzer target is not enough, since different fuzzers are used and not all
......
......@@ -29,6 +29,12 @@ void InterpretAndExecuteModule(Isolate* isolate,
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();
class WasmExecutionFuzzer {
public:
virtual ~WasmExecutionFuzzer() = default;
......
......@@ -24,16 +24,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// 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.
#define ENABLE_STAGED_FEATURES(feat, desc, val) \
i::FlagScope<bool> enable_##feat(&i::FLAG_experimental_wasm_##feat, true);
FOREACH_WASM_STAGING_FEATURE_FLAG(ENABLE_STAGED_FEATURES)
#undef ENABLE_STAGED_FEATURES
i::wasm::fuzzer::OneTimeEnableStagedWasmFeatures();
// We reduce the maximum memory size and table size of WebAssembly instances
// to avoid OOMs in the fuzzer.
i::FlagScope<uint32_t> max_mem_flag_scope(&i::FLAG_wasm_max_mem_pages, 32);
i::FlagScope<uint32_t> max_table_size_scope(&i::FLAG_wasm_max_table_size,
100);
i::FLAG_wasm_max_mem_pages = 32;
i::FLAG_wasm_max_table_size = 100;
v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
v8::Isolate* isolate = support->GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment