diff options
-rw-r--r-- | src/ir/memory-utils.h | 1 | ||||
-rw-r--r-- | src/passes/MemoryPacking.cpp | 1 | ||||
-rw-r--r-- | src/wasm-binary.h | 9 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 4 | ||||
-rw-r--r-- | src/wasm-limits.h | 36 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 1 | ||||
-rw-r--r-- | test/lit/exec/table.grow.wast | 28 |
7 files changed, 71 insertions, 9 deletions
diff --git a/src/ir/memory-utils.h b/src/ir/memory-utils.h index 7c19720ce..d86fb941a 100644 --- a/src/ir/memory-utils.h +++ b/src/ir/memory-utils.h @@ -23,6 +23,7 @@ #include "literal.h" #include "wasm-binary.h" #include "wasm-builder.h" +#include "wasm-limits.h" #include "wasm.h" namespace wasm::MemoryUtils { diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp index 5ecbc5872..064d74e36 100644 --- a/src/passes/MemoryPacking.cpp +++ b/src/passes/MemoryPacking.cpp @@ -37,6 +37,7 @@ #include "support/stdckdint.h" #include "wasm-binary.h" #include "wasm-builder.h" +#include "wasm-limits.h" #include "wasm.h" namespace wasm { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 4f0796601..6fd082f79 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -43,15 +43,6 @@ enum { MaxLEB32Bytes = 5, }; -// wasm VMs on the web have decided to impose some limits on what they -// accept -enum WebLimitations : uint32_t { - MaxDataSegments = 100 * 1000, - MaxFunctionBodySize = 128 * 1024, - MaxFunctionLocals = 50 * 1000, - MaxFunctionParams = 1000 -}; - template<typename T, typename MiniT> struct LEB { static_assert(sizeof(MiniT) == 1, "MiniT must be a byte"); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 059f2d950..a9bba774b 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -35,6 +35,7 @@ #include "support/stdckdint.h" #include "support/string.h" #include "wasm-builder.h" +#include "wasm-limits.h" #include "wasm-traversal.h" #include "wasm.h" @@ -3138,6 +3139,9 @@ public: return fail; } Index newSize = tableSize + delta; + if (newSize > WebLimitations::MaxTableSize) { + return fail; + } if (!info.interface->growTable( tableName, valueFlow.getSingleValue(), tableSize, newSize)) { // We failed to grow the table in practice, even though it was valid diff --git a/src/wasm-limits.h b/src/wasm-limits.h new file mode 100644 index 000000000..0e1863fba --- /dev/null +++ b/src/wasm-limits.h @@ -0,0 +1,36 @@ +/* + * Copyright 2024 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_wasm_limits_h +#define wasm_wasm_limits_h + +#include <stdint.h> + +namespace wasm { + +// wasm VMs on the web have decided to impose some limits on what they +// accept (see e.g. https://github.com/v8/v8/blob/main/src/wasm/wasm-limits.h). +enum WebLimitations : uint32_t { + MaxDataSegments = 100 * 1000, + MaxTableSize = 10 * 1000 * 1000, + MaxFunctionBodySize = 128 * 1024, + MaxFunctionLocals = 50 * 1000, + MaxFunctionParams = 1000 +}; + +} // namespace wasm + +#endif // wasm_wasm_limits_h diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b655395bf..d7c052a9f 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -26,6 +26,7 @@ #include "support/string.h" #include "wasm-binary.h" #include "wasm-debug.h" +#include "wasm-limits.h" #include "wasm-stack.h" #define DEBUG_TYPE "binary" diff --git a/test/lit/exec/table.grow.wast b/test/lit/exec/table.grow.wast new file mode 100644 index 000000000..83a124566 --- /dev/null +++ b/test/lit/exec/table.grow.wast @@ -0,0 +1,28 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. + +;; RUN: wasm-opt %s -all --fuzz-exec-before -q -o /dev/null 2>&1 | filecheck %s + +(module + (table $0 0 funcref) + + ;; CHECK: [fuzz-exec] calling just-right + ;; CHECK-NEXT: [fuzz-exec] note result: just-right => 0 + (func $just-right (export "just-right") (result i32) + ;; Growing up to the limit of 10*1000*1000 will succeed. + (table.grow $0 + (ref.null nofunc) + (i32.const 10000000) + ) + ) + + ;; CHECK: [fuzz-exec] calling too-much + ;; CHECK-NEXT: [fuzz-exec] note result: too-much => -1 + (func $too-much (export "too-much") (result i32) + ;; Growing beyond the limit will error and return -1. + (table.grow $0 + (ref.null nofunc) + (i32.const 10000001) + ) + ) +) + |