interpreter: vectors should not be committed to memory if OOB (#1949)

This commit is contained in:
Edoardo Vacchi
2024-01-24 07:18:23 -08:00
committed by GitHub
parent 156009932b
commit aa51c60cfb
4 changed files with 36 additions and 2 deletions
+4 -2
View File
@@ -2078,10 +2078,12 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance
case wazeroir.OperationKindV128Store:
hi, lo := ce.popValue(), ce.popValue()
offset := ce.popMemoryOffset(op)
if ok := memoryInst.WriteUint64Le(offset, lo); !ok {
// Write the upper bytes first to trigger an early error if the memory access is out of bounds.
// Otherwise, the lower bytes might be written to memory, but the upper bytes might not.
if ok := memoryInst.WriteUint64Le(offset+8, hi); !ok {
panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
}
if ok := memoryInst.WriteUint64Le(offset+8, hi); !ok {
if ok := memoryInst.WriteUint64Le(offset, lo); !ok {
panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
}
frame.pc++
@@ -762,3 +762,22 @@ func Test1846(t *testing.T) {
require.Equal(t, uint64(0), hi)
})
}
// Test1847 verifies that an attempt to write a v128 value to an OOB memory location
// does not result in a partial write (e.g. lower 64 bits) to memory.
func Test1949(t *testing.T) {
if !platform.CompilerSupported() {
return
}
const offset = 65526
run(t, func(t *testing.T, r wazero.Runtime) {
mod, err := r.Instantiate(ctx, getWasmBinary(t, "1949"))
require.NoError(t, err)
_, err = mod.ExportedFunction("").Call(ctx)
require.Error(t, err)
read, ok := mod.Memory().Read(offset, 8)
require.True(t, ok)
require.Equal(t, []byte{0xfe, 0xca, 0xfe, 0xca, 0, 0, 0, 0}, read)
})
}
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
(module
(func
i32.const 0
i32.const 0xcafecafe
i32.store offset=65526 align=1
i32.const 0
v128.const i32x4 0xc1c1c1c1 0xcacac1c1 0xcacacaca 0xcacacaca
v128.store offset=65526 align=1
)
(memory (;0;) 1 7)
(export "" (func 0))
)