summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-11-11 12:08:08 -0800
committerGitHub <noreply@github.com>2022-11-11 20:08:08 +0000
commitcf908c7976d02a9d3d4810a2b5a04e502e4efed2 (patch)
treeac04d8c683903cc76b6e95668bf850f03f9b4be8 /src
parent3928189214e03430bbc9f2b51c6af3887b465160 (diff)
downloadbinaryen-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.cpp2
-rw-r--r--src/wasm-interpreter.h3
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);