Commit 40738e6c authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[wasm] Be more strict about allowed SIMD opcodes

This makes some checks a bit stricter to avoid accepting illegal relaxed
SIMD opcodes.

1) The default case in the Liftoff compiler should be UNREACHABLE,
   such that the switch case is required to cover all defined opcodes.
2) The {WasmOpcodes::IsRelaxedSimdOpcode} wrongly also returned {true}
   for opcodes like 0xfd300. We should really check nibbles 3-5 for the
   exact value 0xfd1.
3) {WasmOpcodes::Signature} was returning a non-null signatures for
   illegal opcodes like 0xfd200, because {IsRelaxedSimdOpcode} returned
   false, and then we would just use the lower bytes for the lookup in
   the SIMD signature table.

R=thibaudm@chromium.org
CC=gdeepti@chromium.org

Bug: chromium:1324081
Change-Id: Idbfde570ccd782e59b47b96e7ca8cc28fa7fae98
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3687309
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80934}
parent 9dcdfaec
......@@ -4119,7 +4119,7 @@ class LiftoffCompiler {
return;
}
default:
unsupported(decoder, kSimd, "simd");
UNREACHABLE();
}
}
......
......@@ -600,13 +600,15 @@ constexpr bool WasmOpcodes::IsThrowingOpcode(WasmOpcode opcode) {
// static
constexpr bool WasmOpcodes::IsRelaxedSimdOpcode(WasmOpcode opcode) {
// Relaxed SIMD opcodes have the SIMD prefix (0xfd) shifted by 12 bits, and
// nibble 3 must be 0x1. I.e. their encoded opcode is in [0xfd100, 0xfd1ff].
static_assert(kSimdPrefix == 0xfd);
#define CHECK_OPCODE(name, opcode, _) \
static_assert((opcode & 0xfd100) == 0xfd100);
static_assert((opcode & 0xfff00) == 0xfd100);
FOREACH_RELAXED_SIMD_OPCODE(CHECK_OPCODE)
#undef CHECK_OPCODE
return (opcode & 0xfd100) == 0xfd100;
return (opcode & 0xfff00) == 0xfd100;
}
constexpr byte WasmOpcodes::ExtractPrefix(WasmOpcode opcode) {
......@@ -695,16 +697,24 @@ constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable =
constexpr const FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
switch (ExtractPrefix(opcode)) {
case 0:
DCHECK_GT(impl::kShortSigTable.size(), opcode);
return impl::kCachedSigs[impl::kShortSigTable[opcode]];
case kSimdPrefix: {
if (IsRelaxedSimdOpcode(opcode))
return impl::kCachedSigs[impl::kRelaxedSimdExprSigTable[opcode & 0xFF]];
return impl::kCachedSigs[impl::kSimdExprSigTable[opcode & 0xFF]];
// Handle SIMD MVP opcodes (in [0xfd00, 0xfdff]).
if (opcode <= 0xfdff) {
DCHECK_LE(0xfd00, opcode);
return impl::kCachedSigs[impl::kSimdExprSigTable[opcode & 0xff]];
}
// Handle relaxed SIMD opcodes (in [0xfd100, 0xfd1ff]).
if (IsRelaxedSimdOpcode(opcode)) {
return impl::kCachedSigs[impl::kRelaxedSimdExprSigTable[opcode & 0xff]];
}
return nullptr;
}
case kAtomicPrefix:
return impl::kCachedSigs[impl::kAtomicExprSigTable[opcode & 0xFF]];
return impl::kCachedSigs[impl::kAtomicExprSigTable[opcode & 0xff]];
case kNumericPrefix:
return impl::kCachedSigs[impl::kNumericExprSigTable[opcode & 0xFF]];
return impl::kCachedSigs[impl::kNumericExprSigTable[opcode & 0xff]];
default:
UNREACHABLE(); // invalid prefix.
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment