Skip to content

Commit 9b61eb3

Browse files
authored
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.
1 parent 06cbe01 commit 9b61eb3

2 files changed

Lines changed: 60 additions & 5 deletions

File tree

src/tools/fuzzing/fuzzing.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,14 @@ void TranslateToFuzzReader::setupMemory() {
224224
auto segment = builder.makeDataSegment();
225225
segment->memory = memory->name;
226226
segment->offset = builder.makeConst(int32_t(0));
227-
segment->setName(Name::fromInt(0), false);
228-
wasm.dataSegments.push_back(std::move(segment));
227+
segment->setName(Names::getValidDataSegmentName(wasm, Name::fromInt(0)),
228+
false);
229229
auto num = upTo(USABLE_MEMORY * 2);
230230
for (size_t i = 0; i < num; i++) {
231231
auto value = upTo(512);
232-
wasm.dataSegments[0]->data.push_back(value >= 256 ? 0 : (value & 0xff));
232+
segment->data.push_back(value >= 256 ? 0 : (value & 0xff));
233233
}
234+
wasm.addDataSegment(std::move(segment));
234235
}
235236
}
236237

src/wasm/wasm-validator.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,7 +3908,7 @@ static void validateTags(Module& module, ValidationInfo& info) {
39083908
}
39093909
}
39103910

3911-
static void validateModule(Module& module, ValidationInfo& info) {
3911+
static void validateStart(Module& module, ValidationInfo& info) {
39123912
// start
39133913
if (module.start.is()) {
39143914
auto func = module.getFunctionOrNull(module.start);
@@ -3924,6 +3924,59 @@ static void validateModule(Module& module, ValidationInfo& info) {
39243924
}
39253925
}
39263926

3927+
namespace {
3928+
template<typename T, typename U>
3929+
void validateModuleMap(Module& module,
3930+
ValidationInfo& info,
3931+
T& list,
3932+
U getter,
3933+
const std::string& kind) {
3934+
// Given a list of module elements (like exports or globals), see that we can
3935+
// get the items using the getter (getExportorNull, etc.). The getter uses the
3936+
// lookup map internally, so this validates that they contain all items in
3937+
// the list.
3938+
for (auto& item : list) {
3939+
auto* ptr = (module.*getter)(item->name);
3940+
if (!ptr) {
3941+
info.fail(kind + " must be found (use updateMaps)", item->name, nullptr);
3942+
} else {
3943+
info.shouldBeEqual(item->name,
3944+
ptr->name,
3945+
item->name,
3946+
"getter must return the correct item");
3947+
}
3948+
}
3949+
3950+
// TODO: Also check there is nothing extraneous in the map, but that would
3951+
// require inspecting private fields of Module.
3952+
}
3953+
} // anonymous namespace
3954+
3955+
static void validateModuleMaps(Module& module, ValidationInfo& info) {
3956+
// Module maps should be up to date.
3957+
validateModuleMap(
3958+
module, info, module.exports, &Module::getExportOrNull, "Export");
3959+
validateModuleMap(
3960+
module, info, module.functions, &Module::getFunctionOrNull, "Function");
3961+
validateModuleMap(
3962+
module, info, module.globals, &Module::getGlobalOrNull, "Global");
3963+
validateModuleMap(module, info, module.tags, &Module::getTagOrNull, "Tag");
3964+
validateModuleMap(module,
3965+
info,
3966+
module.elementSegments,
3967+
&Module::getElementSegmentOrNull,
3968+
"ElementSegment");
3969+
validateModuleMap(
3970+
module, info, module.memories, &Module::getMemoryOrNull, "Memory");
3971+
validateModuleMap(module,
3972+
info,
3973+
module.dataSegments,
3974+
&Module::getDataSegmentOrNull,
3975+
"DataSegment");
3976+
validateModuleMap(
3977+
module, info, module.tables, &Module::getTableOrNull, "Table");
3978+
}
3979+
39273980
static void validateFeatures(Module& module, ValidationInfo& info) {
39283981
if (module.features.hasGC()) {
39293982
info.shouldBeTrue(module.features.hasReferenceTypes(),
@@ -4004,7 +4057,8 @@ bool WasmValidator::validate(Module& module, Flags flags) {
40044057
validateDataSegments(module, info);
40054058
validateTables(module, info);
40064059
validateTags(module, info);
4007-
validateModule(module, info);
4060+
validateStart(module, info);
4061+
validateModuleMaps(module, info);
40084062
validateFeatures(module, info);
40094063
if (info.closedWorld) {
40104064
validateClosedWorldInterface(module, info);

0 commit comments

Comments
 (0)