Commit 73a988a0 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Verify expressions do not cross control boundaries in WASM.

This catches malformed code like the following example:

<expr>
<block begin>
<expr>
<binop>
<end>

Which is illegal because the inputs to the binop cross the block boundary.

R=rossberg@chromium.org,ahaas@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/1961853002
Cr-Commit-Position: refs/heads/master@{#36103}
parent 434ef2cc
...@@ -487,9 +487,9 @@ class SR_WasmDecoder : public WasmDecoder { ...@@ -487,9 +487,9 @@ class SR_WasmDecoder : public WasmDecoder {
SsaEnv* ssa_env_; SsaEnv* ssa_env_;
ZoneVector<LocalType> local_type_vec_; ZoneVector<LocalType> local_type_vec_; // types of local variables.
ZoneVector<Value> stack_; ZoneVector<Value> stack_; // stack of values.
ZoneVector<Control> control_; ZoneVector<Control> control_; // stack of blocks, loops, and ifs.
inline bool build() { return builder_ && ssa_env_->go(); } inline bool build() { return builder_ && ssa_env_->go(); }
...@@ -1157,7 +1157,8 @@ class SR_WasmDecoder : public WasmDecoder { ...@@ -1157,7 +1157,8 @@ class SR_WasmDecoder : public WasmDecoder {
} }
Value Pop() { Value Pop() {
if (stack_.empty()) { size_t limit = control_.empty() ? 0 : control_.back().stack_depth;
if (stack_.size() <= limit) {
Value val = {pc_, nullptr, kAstStmt}; Value val = {pc_, nullptr, kAstStmt};
error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_));
return val; return val;
......
...@@ -307,16 +307,30 @@ TEST_F(AstDecoderTest, Binops_off_end) { ...@@ -307,16 +307,30 @@ TEST_F(AstDecoderTest, Binops_off_end) {
byte code4[] = {kExprGetLocal, 0, 0, 0}; // [expr] [opcode] [opcode] byte code4[] = {kExprGetLocal, 0, 0, 0}; // [expr] [opcode] [opcode]
for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) { for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) {
code4[1] = kInt32BinopOpcodes[i]; code4[2] = kInt32BinopOpcodes[i];
code4[3] = kInt32BinopOpcodes[i]; code4[3] = kInt32BinopOpcodes[i];
EXPECT_FAILURE(sigs.i_i(), code4); EXPECT_FAILURE(sigs.i_i(), code4);
} }
} }
TEST_F(AstDecoderTest, BinopsAcrossBlock1) {
static const byte code[] = {WASM_ZERO, kExprBlock, WASM_ZERO, kExprI32Add,
kExprEnd};
EXPECT_FAILURE(sigs.i_i(), code);
}
TEST_F(AstDecoderTest, BinopsAcrossBlock2) {
static const byte code[] = {WASM_ZERO, WASM_ZERO, kExprBlock, kExprI32Add,
kExprEnd};
EXPECT_FAILURE(sigs.i_i(), code);
}
TEST_F(AstDecoderTest, BinopsAcrossBlock3) {
static const byte code[] = {WASM_ZERO, WASM_ZERO, kExprIf, kExprI32Add,
kExprElse, kExprI32Add, kExprEnd};
EXPECT_FAILURE(sigs.i_i(), code);
}
//===================================================================
//== Statements
//===================================================================
TEST_F(AstDecoderTest, Nop) { TEST_F(AstDecoderTest, Nop) {
static const byte code[] = {kExprNop}; static const byte code[] = {kExprNop};
EXPECT_VERIFIES(sigs.v_v(), code); EXPECT_VERIFIES(sigs.v_v(), code);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment