Skip to content

Commit 2bee4bb

Browse files
authored
[EH] Fuzzer: Fix infinite loop with nested exnrefs (#7294)
When we need an exnref value we may create a try-catch with a throw (so when we catch it, we get an exnref). But if the exception tag contains an exnref, then we will try to create another exnref in the throw, leading to recursion (possibly infinite). To avoid this, just create a trivial tag with no values when we just want a trivial value.
1 parent 60d5626 commit 2bee4bb

2 files changed

Lines changed: 24 additions & 3 deletions

File tree

src/tools/fuzzing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ class TranslateToFuzzReader {
200200

201201
Index numAddedFunctions = 0;
202202

203+
// The name of an empty tag.
204+
Name trivialTag;
205+
203206
// RAII helper for managing the state used to create a single function.
204207
struct FunctionCreationContext {
205208
TranslateToFuzzReader& parent;

src/tools/fuzzing/fuzzing.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4830,10 +4830,28 @@ Expression* TranslateToFuzzReader::makeI31Get(Type type) {
48304830

48314831
Expression* TranslateToFuzzReader::makeThrow(Type type) {
48324832
assert(type == Type::unreachable);
4833-
if (wasm.tags.empty()) {
4834-
addTag();
4833+
Tag* tag;
4834+
if (trivialNesting) {
4835+
// We are nested under a makeTrivial call, so only emit something trivial.
4836+
// Get (or create) a trivial tag, so we have no operands (and will not call
4837+
// make(), below). Otherwise, we might recurse very deeply if we threw a
4838+
// tag that contains an exnref (for which we may end up creating yet another
4839+
// throw in a try).
4840+
if (!trivialTag) {
4841+
auto newTag = builder.makeTag(Names::getValidTagName(wasm, "tag$"),
4842+
Signature(Type::none, Type::none));
4843+
tag = wasm.addTag(std::move(newTag));
4844+
trivialTag = tag->name;
4845+
} else {
4846+
tag = wasm.getTag(trivialTag);
4847+
}
4848+
} else {
4849+
// Get a random tag, adding a random one if necessary.
4850+
if (wasm.tags.empty()) {
4851+
addTag();
4852+
}
4853+
tag = pick(wasm.tags).get();
48354854
}
4836-
auto* tag = pick(wasm.tags).get();
48374855
auto tagType = tag->params();
48384856
std::vector<Expression*> operands;
48394857
for (auto t : tagType) {

0 commit comments

Comments
 (0)