Skip to content

Commit 5c48f3b

Browse files
authored
Fix address overflow bug in wasm2c (#1401)
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.
1 parent 5e16bf1 commit 5c48f3b

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

src/c-writer.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -2080,10 +2080,10 @@ void CWriter::Write(const LoadExpr& expr) {
20802080

20812081
Type result_type = expr.opcode.GetResultType();
20822082
Write(StackVar(0, result_type), " = ", func, "(", ExternalPtr(memory->name),
2083-
", (u64)(", StackVar(0));
2083+
", (u64)(", StackVar(0), ")");
20842084
if (expr.offset != 0)
2085-
Write(" + ", expr.offset);
2086-
Write("));", Newline());
2085+
Write(" + ", expr.offset, "u");
2086+
Write(");", Newline());
20872087
DropTypes(1);
20882088
PushType(result_type);
20892089
}
@@ -2108,10 +2108,10 @@ void CWriter::Write(const StoreExpr& expr) {
21082108
assert(module_->memories.size() == 1);
21092109
Memory* memory = module_->memories[0];
21102110

2111-
Write(func, "(", ExternalPtr(memory->name), ", (u64)(", StackVar(1));
2111+
Write(func, "(", ExternalPtr(memory->name), ", (u64)(", StackVar(1), ")");
21122112
if (expr.offset != 0)
21132113
Write(" + ", expr.offset);
2114-
Write("), ", StackVar(0), ");", Newline());
2114+
Write(", ", StackVar(0), ");", Newline());
21152115
DropTypes(2);
21162116
}
21172117

test/wasm2c/address-overflow.txt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
;;; TOOL: run-spec-wasm2c
2+
(module
3+
(memory 1)
4+
(func (export "test") (param i32)
5+
local.get 0
6+
i32.load8_u offset=1
7+
drop)
8+
)
9+
(assert_trap (invoke "test" (i32.const -1)) "out of bounds memory access")
10+
(;; STDOUT ;;;
11+
1/1 tests passed.
12+
;;; STDOUT ;;)

0 commit comments

Comments
 (0)