Skip to content

Commit ff423ae

Browse files
authored
Fix bug in SIMDLoadStoreLane interpretation (WebAssembly#7237)
The interpreter incorrectly trapped on OOB addresses before evaluating the vector operand. This bug became visible when the vector operand had side effects. Reorder the code to fix the problem.
1 parent 7074d87 commit ff423ae

File tree

2 files changed

+51
-9
lines changed

2 files changed

+51
-9
lines changed

src/wasm-interpreter.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3812,20 +3812,20 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
38123812
}
38133813
Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
38143814
NOTE_ENTER("SIMDLoadStoreLane");
3815-
Flow flow = self()->visit(curr->ptr);
3816-
if (flow.breaking()) {
3817-
return flow;
3815+
Flow ptrFlow = self()->visit(curr->ptr);
3816+
if (ptrFlow.breaking()) {
3817+
return ptrFlow;
38183818
}
38193819
NOTE_EVAL1(flow);
3820+
Flow vecFlow = self()->visit(curr->vec);
3821+
if (vecFlow.breaking()) {
3822+
return vecFlow;
3823+
}
38203824
auto info = getMemoryInstanceInfo(curr->memory);
38213825
auto memorySize = info.instance->getMemorySize(info.name);
38223826
Address addr = info.instance->getFinalAddress(
3823-
curr, flow.getSingleValue(), curr->getMemBytes(), memorySize);
3824-
flow = self()->visit(curr->vec);
3825-
if (flow.breaking()) {
3826-
return flow;
3827-
}
3828-
Literal vec = flow.getSingleValue();
3827+
curr, ptrFlow.getSingleValue(), curr->getMemBytes(), memorySize);
3828+
Literal vec = vecFlow.getSingleValue();
38293829
switch (curr->op) {
38303830
case Load8LaneVec128:
38313831
case Store8LaneVec128: {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.
2+
3+
;; RUN: wasm-opt %s -all --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s
4+
5+
;; Regression test for a bug where the vector operand to SIMDLoadStoreLane was
6+
;; not evaluated if the preceding ptr operand was OOB.
7+
8+
(module
9+
(memory $mem 1 1)
10+
(global $g (mut i32) (i32.const 0))
11+
12+
;; CHECK: [fuzz-exec] calling oob
13+
;; CHECK-NEXT: [trap final > memory: 18446744073709551615 > 65536]
14+
(func $oob (export "oob")
15+
(drop
16+
;; This should trap, but not until after setting the global.
17+
(v128.load64_lane 0
18+
(i32.const -1)
19+
(block (result v128)
20+
(global.set $g
21+
(i32.const 1)
22+
)
23+
(v128.const i32x4 0 0 0 0)
24+
)
25+
)
26+
)
27+
)
28+
29+
;; CHECK: [fuzz-exec] calling get
30+
;; CHECK-NEXT: [fuzz-exec] note result: get => 1
31+
(func $get (export "get") (result i32)
32+
;; This should be 1
33+
(global.get $g)
34+
)
35+
)
36+
;; CHECK: [fuzz-exec] calling oob
37+
;; CHECK-NEXT: [trap final > memory: 18446744073709551615 > 65536]
38+
39+
;; CHECK: [fuzz-exec] calling get
40+
;; CHECK-NEXT: [fuzz-exec] note result: get => 1
41+
;; CHECK-NEXT: [fuzz-exec] comparing get
42+
;; CHECK-NEXT: [fuzz-exec] comparing oob

0 commit comments

Comments
 (0)