Skip to content

Commit

Permalink
Fix address overflow bug in wasm2c
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 committed Apr 29, 2020
1 parent 068f604 commit a216de0
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 a216de0

Please sign in to comment.