Skip to content

Commit

Permalink
Fix address overflow bug in wasm2c (#1401)
Browse files Browse the repository at this point in the history
This only occurs when the immediate offset is small (`int` sized). The
stack offset is `u32` and the immediate is an `int`, so the usual
arithmetic conversions converts the result to a `u32`, which wraps the
address before checking for overflow.

There are already spec tests for overflow, but these use an offset of
`4294967295`, which is `long` (at least on LP64 systems). This means
that the sum's type is `u32 + long` which is `long`. This is why the
tests pass. I've added additional tests for these cases here:
WebAssembly/spec#1188

This fixes issue #1400.
  • Loading branch information
binji authored Apr 29, 2020
1 parent 5e16bf1 commit 5c48f3b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/c-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2080,10 +2080,10 @@ void CWriter::Write(const LoadExpr& expr) {

Type result_type = expr.opcode.GetResultType();
Write(StackVar(0, result_type), " = ", func, "(", ExternalPtr(memory->name),
", (u64)(", StackVar(0));
", (u64)(", StackVar(0), ")");
if (expr.offset != 0)
Write(" + ", expr.offset);
Write("));", Newline());
Write(" + ", expr.offset, "u");
Write(");", Newline());
DropTypes(1);
PushType(result_type);
}
Expand All @@ -2108,10 +2108,10 @@ void CWriter::Write(const StoreExpr& expr) {
assert(module_->memories.size() == 1);
Memory* memory = module_->memories[0];

Write(func, "(", ExternalPtr(memory->name), ", (u64)(", StackVar(1));
Write(func, "(", ExternalPtr(memory->name), ", (u64)(", StackVar(1), ")");
if (expr.offset != 0)
Write(" + ", expr.offset);
Write("), ", StackVar(0), ");", Newline());
Write(", ", StackVar(0), ");", Newline());
DropTypes(2);
}

Expand Down
12 changes: 12 additions & 0 deletions test/wasm2c/address-overflow.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
;;; TOOL: run-spec-wasm2c
(module
(memory 1)
(func (export "test") (param i32)
local.get 0
i32.load8_u offset=1
drop)
)
(assert_trap (invoke "test" (i32.const -1)) "out of bounds memory access")
(;; STDOUT ;;;
1/1 tests passed.
;;; STDOUT ;;)

0 comments on commit 5c48f3b

Please sign in to comment.