Skip to content
Merged
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,15 @@ void TranslateToFuzzReader::finalizeTable() {
}
table->initial = std::max(table->initial, maxOffset);
});

// Clamp the table size to something reasonable, as huge tables (say of size
// 4GB) are very slow to interpret. Also, this avoids an issue where a
// segment has an offset at an address larger than kMaxSize, which traps at
// startup but would be a non-validating module for us to emit.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused by this comment. Would the segment fail to validate or trap? It can't do both at the same time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A segment with a huge but valid offset that is larger than kMaxSize will trap. But we fail to validate if we raise initial to such sizes. This is due to the max size being 32 bits but Address being 64 bits. Perhaps another way to fix this is to refactor Address to be 32 bits in wasm32, but I think we had a reason for the current approach.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, so big segment offsets lead to traps and big tables lead to validation errors. Makes sense. I guess I don't understand the connection between them, though. Is the fuzzer generating segment offsets and table sizes based off of each other?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the code adjacent to this (right above it) increases initial based on the segments it sees, that is, it is trying to avoid a trap by ensuring a big-enough initial size.

const Address ReasonableMaxTableSize = 10000;
table->initial = std::min(table->initial, ReasonableMaxTableSize);
assert(ReasonableMaxTableSize <= Table::kMaxSize);

table->max = oneIn(2) ? Address(Table::kUnlimitedSize) : table->initial;
// Avoid an imported table (which the fuzz harness would need to handle).
table->module = table->base = Name();
Expand Down