diff options
author | Thomas Lively <tlively@google.com> | 2022-11-11 12:08:08 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-11 20:08:08 +0000 |
commit | cf908c7976d02a9d3d4810a2b5a04e502e4efed2 (patch) | |
tree | ac04d8c683903cc76b6e95668bf850f03f9b4be8 /src | |
parent | 3928189214e03430bbc9f2b51c6af3887b465160 (diff) | |
download | binaryen-cf908c7976d02a9d3d4810a2b5a04e502e4efed2.tar.gz binaryen-cf908c7976d02a9d3d4810a2b5a04e502e4efed2.tar.bz2 binaryen-cf908c7976d02a9d3d4810a2b5a04e502e4efed2.zip |
Fix two fuzz bugs with ArrayNewSeg (#5242)
First, we forgot to note the type annotation on `ArrayNewSeg` instructions, so
in small modules where these are the only annotated instructions, the type
section would be incomplete.
Second, in the interpreter we were reserving space for the array before checking
that the segment access was valid. This could cause huge allocations that threw
bad_alloc exceptions before the interpreter could get around to trapping. Fix
the problem by reserving the array after validating the arguements.
Fixes #5236.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/module-utils.cpp | 2 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 3 |
2 files changed, 4 insertions, 1 deletions
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 744f62682..c10a45b15 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -66,6 +66,8 @@ struct CodeScanner counts.note(curr->type); } else if (curr->is<ArrayNew>()) { counts.note(curr->type); + } else if (curr->is<ArrayNewSeg>()) { + counts.note(curr->type); } else if (curr->is<ArrayInit>()) { counts.note(curr->type); } else if (auto* cast = curr->dynCast<RefCast>()) { diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 06fee0317..165bfd18a 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -3519,7 +3519,6 @@ public: WASM_UNUSED(elemType); Literals contents; - contents.reserve(size); switch (curr->op) { case NewData: { @@ -3532,6 +3531,7 @@ public: end > seg.data.size()) { trap("out of bounds segment access in array.new_data"); } + contents.reserve(size); for (Index i = offset; i < end; i += elemBytes) { auto addr = (void*)&seg.data[i]; contents.push_back(Literal::makeFromMemory(addr, element)); @@ -3546,6 +3546,7 @@ public: if (end > seg.data.size()) { trap("out of bounds segment access in array.new_elem"); } + contents.reserve(size); for (Index i = offset; i < end; ++i) { auto val = self()->visit(seg.data[i]).getSingleValue(); contents.push_back(val); |