diff --git a/internal/engine/compiler/compiler_vec_test.go b/internal/engine/compiler/compiler_vec_test.go index 3ce70c6c..7f715d50 100644 --- a/internal/engine/compiler/compiler_vec_test.go +++ b/internal/engine/compiler/compiler_vec_test.go @@ -414,6 +414,17 @@ func TestCompiler_compileV128Load(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, }, }, + { + name: "32zero on ceil", loadType: wazeroir.V128LoadType32zero, + offset: wasm.MemoryPageSize - 4, + memSetupFn: func(buf []byte) { + copy(buf[wasm.MemoryPageSize-8:], []byte{ + 1, 0xff, 3, 0xff, + 5, 6, 0xff, 8, + }) + }, + exp: [16]byte{5, 6, 0xff, 8}, + }, { name: "64zero offset=0", loadType: wazeroir.V128LoadType64zero, offset: 0, memSetupFn: func(buf []byte) { @@ -440,6 +451,17 @@ func TestCompiler_compileV128Load(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, }, }, + { + name: "64zero on ceil", loadType: wazeroir.V128LoadType64zero, + offset: wasm.MemoryPageSize - 8, + memSetupFn: func(buf []byte) { + copy(buf[wasm.MemoryPageSize-16:], []byte{ + 1, 0xff, 3, 0xff, 5, 6, 7, 0xff, + 9, 0xff, 11, 12, 13, 14, 15, + }) + }, + exp: [16]byte{9, 0xff, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0}, + }, { name: "8splat offset=0", loadType: wazeroir.V128LoadType8Splat, offset: 0, memSetupFn: func(buf []byte) { @@ -548,6 +570,8 @@ func TestCompiler_compileV128Load(t *testing.T) { require.NoError(t, err) env.exec(code) + require.Equal(t, nativeCallStatusCodeReturned, env.callEngine().statusCode) + require.Equal(t, uint64(2), env.stackPointer()) lo, hi := env.stackTopAsV128() diff --git a/internal/engine/compiler/impl_vec_arm64.go b/internal/engine/compiler/impl_vec_arm64.go index 98f04d52..9d00920e 100644 --- a/internal/engine/compiler/impl_vec_arm64.go +++ b/internal/engine/compiler/impl_vec_arm64.go @@ -234,7 +234,7 @@ func (c *arm64Compiler) compileV128Load(o *wazeroir.OperationV128Load) (err erro c.assembler.CompileRegisterToRegister(arm64.ADD, arm64ReservedRegisterForMemory, offset) c.assembler.CompileMemoryToVectorRegister(arm64.LD1R, offset, 0, result, arm64.VectorArrangement2D) case wazeroir.V128LoadType32zero: - offset, err := c.compileMemoryAccessOffsetSetup(o.Arg.Offset, 16) + offset, err := c.compileMemoryAccessOffsetSetup(o.Arg.Offset, 4) if err != nil { return err } @@ -242,7 +242,7 @@ func (c *arm64Compiler) compileV128Load(o *wazeroir.OperationV128Load) (err erro arm64ReservedRegisterForMemory, offset, result, arm64.VectorArrangementS, ) case wazeroir.V128LoadType64zero: - offset, err := c.compileMemoryAccessOffsetSetup(o.Arg.Offset, 16) + offset, err := c.compileMemoryAccessOffsetSetup(o.Arg.Offset, 8) if err != nil { return err } diff --git a/internal/integration_test/fuzzcases/fuzzcases_test.go b/internal/integration_test/fuzzcases/fuzzcases_test.go index 099f072e..615a6164 100644 --- a/internal/integration_test/fuzzcases/fuzzcases_test.go +++ b/internal/integration_test/fuzzcases/fuzzcases_test.go @@ -184,6 +184,18 @@ func Test717(t *testing.T) { }) } +func Test718(t *testing.T) { + run(t, func(t *testing.T, r wazero.Runtime) { + mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 718)) + require.NoError(t, err) + + f := mod.ExportedFunction("v128.load_zero on the ceil") + require.NotNil(t, f) + _, err = f.Call(ctx) + require.NoError(t, err) + }) +} + func Test719(t *testing.T) { run(t, func(t *testing.T, r wazero.Runtime) { mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 719)) diff --git a/internal/integration_test/fuzzcases/testdata/718.wasm b/internal/integration_test/fuzzcases/testdata/718.wasm new file mode 100644 index 00000000..5b525e32 Binary files /dev/null and b/internal/integration_test/fuzzcases/testdata/718.wasm differ diff --git a/internal/integration_test/fuzzcases/testdata/718.wat b/internal/integration_test/fuzzcases/testdata/718.wat new file mode 100644 index 00000000..a2c6adab --- /dev/null +++ b/internal/integration_test/fuzzcases/testdata/718.wat @@ -0,0 +1,19 @@ +(module + (func + i32.const 0 + ;; The ceil of the load operation equals 65528 + 8(=this loads 64-bit = 8 bytes). + ;; Therefore, this shouldn't result in out of bounds. + v128.load64_zero offset=65528 + + i32.const 0 + ;; The ceil of the load operation equals 65532 + 4(=this loads 32-bit = 4 bytes). + ;; Therefore, this shouldn't result in out of bounds. + v128.load32_zero offset=65532 + + ;; Drop the loaded values as they are unneede for tests. + drop + drop + ) + (memory 1 1) + (export "v128.load_zero on the ceil" (func 0)) +)