diff options
-rw-r--r-- | src/ir/effects.h | 17 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 7 | ||||
-rw-r--r-- | test/passes/Oz_fuzz-exec_all-features.txt | 13 | ||||
-rw-r--r-- | test/passes/Oz_fuzz-exec_all-features.wast | 10 |
4 files changed, 41 insertions, 6 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h index de228c3f4..3d71a8433 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -22,8 +22,7 @@ namespace wasm { -// Look for side effects, including control flow -// TODO: optimize +// Analyze various possible effects. class EffectAnalyzer { public: @@ -77,9 +76,23 @@ public: bool writesHeap = false; // A trap, either from an unreachable instruction, or from an implicit trap // that we do not ignore (see below). + // // Note that we ignore trap differences, so it is ok to reorder traps with // each other, but it is not ok to remove them or reorder them with other // effects in a noticeable way. + // + // Note also that we ignore runtime-dependent traps, such as hitting a + // recursion limit or running out of memory. Such traps are not part of wasm's + // official semantics, and they can occur anywhere: *any* instruction could in + // theory be implemented by a VM call (as will be the case when running in an + // interpreter), and such a call could run out of stack or memory in + // principle. To put it another way, an i32 division by zero is the program + // doing something bad that causes a trap, but the VM running out of memory is + // the VM doing something bad - and therefore the VM behaving in a way that is + // not according to the wasm semantics - and we do not model such things. Note + // that as a result we do *not* mark things like GC allocation instructions as + // having side effects, which has the nice benefit of making it possible to + // eliminate an allocation whose result is not captured. bool trap = false; // A trap from an instruction like a load or div/rem, which may trap on corner // cases. If we do not ignore implicit traps then these are counted as a trap. diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 9118eaae1..1c8377127 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1617,6 +1617,13 @@ public: } const auto& element = curr->rtt->type.getHeapType().getArray().element; Index num = size.getSingleValue().geti32(); + // Arbitrary deterministic limit on size. If we need to allocate a Literals + // vector that takes around 1-2GB of memory then we are likely to hit memory + // limits on 32-bit machines, and in particular on wasm32 VMs that do not + // have 4GB support, so give up there. + if (num >= (1 << 30) / sizeof(Literal)) { + trap("allocation failure"); + } Literals data(num); if (curr->isWithDefault()) { for (Index i = 0; i < num; i++) { diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt index 0f90a6ef7..5d00a3db1 100644 --- a/test/passes/Oz_fuzz-exec_all-features.txt +++ b/test/passes/Oz_fuzz-exec_all-features.txt @@ -25,13 +25,15 @@ [LoggingExternalInterface logging 0] [fuzz-exec] calling br_on_data [LoggingExternalInterface logging 1] -[fuzz-exec] calling $rtt-and-cast-on-func +[fuzz-exec] calling rtt-and-cast-on-func [LoggingExternalInterface logging 0] [LoggingExternalInterface logging 1] [LoggingExternalInterface logging 2] [LoggingExternalInterface logging 1337] [LoggingExternalInterface logging 3] [trap cast error] +[fuzz-exec] calling array-alloc-failure +[trap allocation failure] (module (type $struct (struct (field (mut i32)))) (type $void_func (func)) @@ -48,7 +50,8 @@ (export "br_on_cast" (func $3)) (export "cast-null-anyref-to-gc" (func $4)) (export "br_on_data" (func $6)) - (export "$rtt-and-cast-on-func" (func $8)) + (export "rtt-and-cast-on-func" (func $8)) + (export "array-alloc-failure" (func $9)) (func $0 (; has Stack IR ;) (local $0 (ref null $struct)) (call $log @@ -235,6 +238,9 @@ (i32.const 4) ) ) + (func $9 (; has Stack IR ;) + (nop) + ) ) [fuzz-exec] calling structs [LoggingExternalInterface logging 0] @@ -263,10 +269,11 @@ [LoggingExternalInterface logging 0] [fuzz-exec] calling br_on_data [LoggingExternalInterface logging 1] -[fuzz-exec] calling $rtt-and-cast-on-func +[fuzz-exec] calling rtt-and-cast-on-func [LoggingExternalInterface logging 0] [LoggingExternalInterface logging 1] [LoggingExternalInterface logging 2] [LoggingExternalInterface logging 1337] [LoggingExternalInterface logging 3] [trap cast error] +[fuzz-exec] calling array-alloc-failure diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast index 34c9a224a..4092f6b34 100644 --- a/test/passes/Oz_fuzz-exec_all-features.wast +++ b/test/passes/Oz_fuzz-exec_all-features.wast @@ -209,7 +209,7 @@ (func $a-void-func (call $log (i32.const 1337)) ) - (func "$rtt-and-cast-on-func" + (func "rtt-and-cast-on-func" (call $log (i32.const 0)) (drop (rtt.canon $void_func) @@ -231,4 +231,12 @@ ;; will never be reached (call $log (i32.const 4)) ) + (func "array-alloc-failure" + (drop + (array.new_default_with_rtt $bytes + (i32.const -1) ;; un-allocatable size (4GB * sizeof(Literal)) + (rtt.canon $bytes) + ) + ) + ) ) |