[wasm-simd] Fix bounds check for load extends

Load extends always load 8 bytes, so the access size does not depend on
MachineType of the load. The MachineType is used for classifying the
lane shape of the 8-byte load.

Also add cctest to load splats and load extends to test OOB. (Note that
load splats access size depends on MachineType).

Add regression test from clusterfuzz, minimized by ahaas@. Remove the
`--no-wasm-trap-handler` flag since we have a no_wasm_traps variant that
should test this flag.

Bug: chromium:1116019
Change-Id: I27ba051d0536ca0f6fd75dd641ca9b78132dafed
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2363291
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69489}
This commit is contained in:
Ng Zhi An 2020-08-18 15:06:22 -07:00 committed by Commit Bot
parent a61393a332
commit a85b5a63f6
4 changed files with 63 additions and 2 deletions

View File

@ -4012,8 +4012,13 @@ Node* WasmGraphBuilder::LoadTransform(wasm::ValueType type, MachineType memtype,
#else #else
// Wasm semantics throw on OOB. Introduce explicit bounds check and // Wasm semantics throw on OOB. Introduce explicit bounds check and
// conditioning when not using the trap handler. // conditioning when not using the trap handler.
index = BoundsCheckMem(memtype.MemSize(), index, offset, position,
kCanOmitBoundsCheck); // Load extends always load 8 bytes.
uint8_t access_size = transform == wasm::LoadTransformationKind::kExtend
? 8
: memtype.MemSize();
index =
BoundsCheckMem(access_size, index, offset, position, kCanOmitBoundsCheck);
LoadTransformation transformation = GetLoadTransformation(memtype, transform); LoadTransformation transformation = GetLoadTransformation(memtype, transform);
LoadKind load_kind = GetLoadKind(mcgraph(), memtype, use_trap_handler()); LoadKind load_kind = GetLoadKind(mcgraph(), memtype, use_trap_handler());

View File

@ -3499,6 +3499,22 @@ void RunLoadSplatTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
CHECK_EQ(x, ReadLittleEndianValue<T>(&global[i])); CHECK_EQ(x, ReadLittleEndianValue<T>(&global[i]));
} }
} }
// Test for OOB.
{
WasmRunner<int32_t, uint32_t> r(execution_tier, lower_simd);
r.builder().AddMemoryElems<T>(kWasmPageSize / sizeof(T));
r.builder().AddGlobal<T>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_LOAD_OP(op, WASM_GET_LOCAL(0))),
WASM_ONE);
// Load splats load sizeof(T) bytes.
for (uint32_t offset = kWasmPageSize - (sizeof(T) - 1);
offset < kWasmPageSize; ++offset) {
CHECK_TRAP(r.Call(offset));
}
}
} }
WASM_SIMD_TEST(S8x16LoadSplat) { WASM_SIMD_TEST(S8x16LoadSplat) {
@ -3574,6 +3590,22 @@ void RunLoadExtendTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
CHECK_EQ(expected, ReadLittleEndianValue<T>(&global[i])); CHECK_EQ(expected, ReadLittleEndianValue<T>(&global[i]));
} }
} }
// Test for OOB.
{
WasmRunner<int32_t, uint32_t> r(execution_tier, lower_simd);
r.builder().AddMemoryElems<S>(kWasmPageSize / sizeof(S));
r.builder().AddGlobal<T>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_LOAD_OP(op, WASM_GET_LOCAL(0))),
WASM_ONE);
// Load extends load 8 bytes, so should trap from -7.
for (uint32_t offset = kWasmPageSize - 7; offset < kWasmPageSize;
++offset) {
CHECK_TRAP(r.Call(offset));
}
}
} }
WASM_SIMD_TEST(I16x8Load8x8U) { WASM_SIMD_TEST(I16x8Load8x8U) {

View File

@ -0,0 +1,23 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-simd
load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
builder.addMemory(16, 32, false);
builder.addType(makeSig([], [kWasmI32]));
// Generate function 1 (out of 1).
builder.addFunction(undefined, 0 /* sig */)
.addBodyWithEnd([
// signature: i_v
// body:
kExprI32Const, 0x00, // i32.const
kSimdPrefix, kExprI16x8Load8x8U, 0x03, 0xff, 0xff, 0x3f, // i16x8.load8x8_u
kSimdPrefix, kExprI16x8ExtractLaneS, 0,
kExprEnd, // end @371
]).exportAs('main');
const instance = builder.instantiate();
assertTraps(kTrapMemOutOfBounds, () => instance.exports.main());

View File

@ -499,6 +499,7 @@ let kExprI64x2Splat = 0x12;
let kExprF32x4Splat = 0x13; let kExprF32x4Splat = 0x13;
let kExprF64x2Splat = 0x14; let kExprF64x2Splat = 0x14;
let kExprI8x16ReplaceLane = 0x17; let kExprI8x16ReplaceLane = 0x17;
let kExprI16x8ExtractLaneS = 0x18;
let kExprI16x8ReplaceLane = 0x1a; let kExprI16x8ReplaceLane = 0x1a;
let kExprI32x4ExtractLane = 0x1b; let kExprI32x4ExtractLane = 0x1b;
let kExprI32x4ReplaceLane = 0x1c; let kExprI32x4ReplaceLane = 0x1c;