Commit 6a892bb4 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Validate the alignment of load and store instructions.

According to the WebAssembly specification the alignment of load and
store instructions has to be less or equal to natural alignment.

R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/2285643002
Cr-Commit-Position: refs/heads/master@{#39131}
parent a804e9b0
......@@ -401,7 +401,7 @@ class WasmDecoder : public Decoder {
FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
{
MemoryAccessOperand operand(this, pc);
MemoryAccessOperand operand(this, pc, UINT32_MAX);
return 1 + operand.length;
}
case kExprBr:
......@@ -1378,7 +1378,9 @@ class WasmFullDecoder : public WasmDecoder {
}
int DecodeLoadMem(LocalType type, MachineType mem_type) {
MemoryAccessOperand operand(this, pc_);
MemoryAccessOperand operand(this, pc_,
ElementSizeLog2Of(mem_type.representation()));
Value index = Pop(0, kAstI32);
TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset,
operand.alignment, position());
......@@ -1387,7 +1389,8 @@ class WasmFullDecoder : public WasmDecoder {
}
int DecodeStoreMem(LocalType type, MachineType mem_type) {
MemoryAccessOperand operand(this, pc_);
MemoryAccessOperand operand(this, pc_,
ElementSizeLog2Of(mem_type.representation()));
Value val = Pop(1, type);
Value index = Pop(0, kAstI32);
BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment,
......
......@@ -185,10 +185,17 @@ struct MemoryAccessOperand {
uint32_t alignment;
uint32_t offset;
unsigned length;
inline MemoryAccessOperand(Decoder* decoder, const byte* pc) {
inline MemoryAccessOperand(Decoder* decoder, const byte* pc,
uint32_t max_alignment) {
unsigned alignment_length;
alignment =
decoder->checked_read_u32v(pc, 1, &alignment_length, "alignment");
if (max_alignment < alignment) {
decoder->error(pc, pc + 1,
"invalid alignment; expected maximum alignment is %u, "
"actual alignment is %u",
max_alignment, alignment);
}
unsigned offset_length;
offset = decoder->checked_read_u32v(pc, 1 + alignment_length,
&offset_length, "offset");
......
......@@ -1444,7 +1444,7 @@ class ThreadImpl : public WasmInterpreter::Thread {
#define LOAD_CASE(name, ctype, mtype) \
case kExpr##name: { \
MemoryAccessOperand operand(&decoder, code->at(pc)); \
MemoryAccessOperand operand(&decoder, code->at(pc), sizeof(ctype)); \
uint32_t index = Pop().to<uint32_t>(); \
size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
if (operand.offset > effective_mem_size || \
......@@ -1476,7 +1476,7 @@ class ThreadImpl : public WasmInterpreter::Thread {
#define STORE_CASE(name, ctype, mtype) \
case kExpr##name: { \
MemoryAccessOperand operand(&decoder, code->at(pc)); \
MemoryAccessOperand operand(&decoder, code->at(pc), sizeof(ctype)); \
WasmVal val = Pop(); \
uint32_t index = Pop().to<uint32_t>(); \
size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
......
......@@ -1093,6 +1093,40 @@ TEST_F(AstDecoderTest, LoadMemOffset) {
}
}
TEST_F(AstDecoderTest, LoadMemAlignment) {
struct {
WasmOpcode instruction;
uint32_t maximum_aligment;
} values[] = {
{kExprI32LoadMem8U, 0}, // --
{kExprI32LoadMem8S, 0}, // --
{kExprI32LoadMem16U, 1}, // --
{kExprI32LoadMem16S, 1}, // --
{kExprI64LoadMem8U, 0}, // --
{kExprI64LoadMem8S, 0}, // --
{kExprI64LoadMem16U, 1}, // --
{kExprI64LoadMem16S, 1}, // --
{kExprI64LoadMem32U, 2}, // --
{kExprI64LoadMem32S, 2}, // --
{kExprI32LoadMem, 2}, // --
{kExprI64LoadMem, 3}, // --
{kExprF32LoadMem, 2}, // --
{kExprF64LoadMem, 3}, // --
};
for (int i = 0; i < arraysize(values); i++) {
for (byte alignment = 0; alignment <= 4; alignment++) {
byte code[] = {kExprI8Const, 0, static_cast<byte>(values[i].instruction),
alignment, ZERO_OFFSET};
if (static_cast<uint32_t>(alignment) <= values[i].maximum_aligment) {
EXPECT_VERIFIES(sigs.v_i(), code);
} else {
EXPECT_FAILURE(sigs.v_i(), code);
}
}
}
}
TEST_F(AstDecoderTest, StoreMemOffset) {
for (int offset = 0; offset < 128; offset += 7) {
byte code[] = {WASM_STORE_MEM_OFFSET(MachineType::Int32(), offset,
......
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