diff options
author | Alon Zakai <azakai@google.com> | 2024-05-23 16:06:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-23 16:06:19 -0700 |
commit | 9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc (patch) | |
tree | 32644530f45fedfff39676c5b8e04203f47a7c17 /src | |
parent | 06cbe01f2774955ed3f23994b3ea1db58e43a4d8 (diff) | |
download | binaryen-9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc.tar.gz binaryen-9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc.tar.bz2 binaryen-9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc.zip |
Fix fuzzer generation of a DataSegment + add validation that would have caught it (#6626)
The DataSegment was manually added to .dataSegments, but we need to add it
using addDataSegment so the maps are updated and getDataSegment(name)
works.
Also add validation that would have caught this earlier: check that each item in
the item lists can be fetched by name.
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 7 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 58 |
2 files changed, 60 insertions, 5 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index f4f059deb..57c7ec6b0 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -224,13 +224,14 @@ void TranslateToFuzzReader::setupMemory() { auto segment = builder.makeDataSegment(); segment->memory = memory->name; segment->offset = builder.makeConst(int32_t(0)); - segment->setName(Name::fromInt(0), false); - wasm.dataSegments.push_back(std::move(segment)); + segment->setName(Names::getValidDataSegmentName(wasm, Name::fromInt(0)), + false); auto num = upTo(USABLE_MEMORY * 2); for (size_t i = 0; i < num; i++) { auto value = upTo(512); - wasm.dataSegments[0]->data.push_back(value >= 256 ? 0 : (value & 0xff)); + segment->data.push_back(value >= 256 ? 0 : (value & 0xff)); } + wasm.addDataSegment(std::move(segment)); } } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e8a4033ef..689872a19 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3908,7 +3908,7 @@ static void validateTags(Module& module, ValidationInfo& info) { } } -static void validateModule(Module& module, ValidationInfo& info) { +static void validateStart(Module& module, ValidationInfo& info) { // start if (module.start.is()) { auto func = module.getFunctionOrNull(module.start); @@ -3924,6 +3924,59 @@ static void validateModule(Module& module, ValidationInfo& info) { } } +namespace { +template<typename T, typename U> +void validateModuleMap(Module& module, + ValidationInfo& info, + T& list, + U getter, + const std::string& kind) { + // Given a list of module elements (like exports or globals), see that we can + // get the items using the getter (getExportorNull, etc.). The getter uses the + // lookup map internally, so this validates that they contain all items in + // the list. + for (auto& item : list) { + auto* ptr = (module.*getter)(item->name); + if (!ptr) { + info.fail(kind + " must be found (use updateMaps)", item->name, nullptr); + } else { + info.shouldBeEqual(item->name, + ptr->name, + item->name, + "getter must return the correct item"); + } + } + + // TODO: Also check there is nothing extraneous in the map, but that would + // require inspecting private fields of Module. +} +} // anonymous namespace + +static void validateModuleMaps(Module& module, ValidationInfo& info) { + // Module maps should be up to date. + validateModuleMap( + module, info, module.exports, &Module::getExportOrNull, "Export"); + validateModuleMap( + module, info, module.functions, &Module::getFunctionOrNull, "Function"); + validateModuleMap( + module, info, module.globals, &Module::getGlobalOrNull, "Global"); + validateModuleMap(module, info, module.tags, &Module::getTagOrNull, "Tag"); + validateModuleMap(module, + info, + module.elementSegments, + &Module::getElementSegmentOrNull, + "ElementSegment"); + validateModuleMap( + module, info, module.memories, &Module::getMemoryOrNull, "Memory"); + validateModuleMap(module, + info, + module.dataSegments, + &Module::getDataSegmentOrNull, + "DataSegment"); + validateModuleMap( + module, info, module.tables, &Module::getTableOrNull, "Table"); +} + static void validateFeatures(Module& module, ValidationInfo& info) { if (module.features.hasGC()) { info.shouldBeTrue(module.features.hasReferenceTypes(), @@ -4004,7 +4057,8 @@ bool WasmValidator::validate(Module& module, Flags flags) { validateDataSegments(module, info); validateTables(module, info); validateTags(module, info); - validateModule(module, info); + validateStart(module, info); + validateModuleMaps(module, info); validateFeatures(module, info); if (info.closedWorld) { validateClosedWorldInterface(module, info); |