diff options
author | Soni L. <EnderMoneyMod@gmail.com> | 2024-08-09 19:29:59 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-09 22:29:59 +0000 |
commit | 63fefe32e7e40efe1050c1908422b29e883c0575 (patch) | |
tree | 3a4f2a56e4344e2295b6b7d7c85cde142ae050fc | |
parent | 3e826ecde1adfba5f88d10d361131405637e65a3 (diff) | |
download | wabt-63fefe32e7e40efe1050c1908422b29e883c0575.tar.gz wabt-63fefe32e7e40efe1050c1908422b29e883c0575.tar.bz2 wabt-63fefe32e7e40efe1050c1908422b29e883c0575.zip |
Harden against invalid alignment (#2411)
-rw-r--r-- | src/binary-reader-ir.cc | 26 | ||||
-rw-r--r-- | src/binary-reader.cc | 29 | ||||
-rw-r--r-- | test/binary/bad-alignment.txt | 5 | ||||
-rw-r--r-- | test/regress/undefined-shifts.txt | 21 |
4 files changed, 61 insertions, 20 deletions
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index a918c39d..8c79cd52 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -806,7 +806,7 @@ Result BinaryReaderIR::OnAtomicLoadExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<AtomicLoadExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnAtomicStoreExpr(Opcode opcode, @@ -814,7 +814,7 @@ Result BinaryReaderIR::OnAtomicStoreExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<AtomicStoreExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnAtomicRmwExpr(Opcode opcode, @@ -822,7 +822,7 @@ Result BinaryReaderIR::OnAtomicRmwExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<AtomicRmwExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode, @@ -830,7 +830,7 @@ Result BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<AtomicRmwCmpxchgExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode, @@ -838,7 +838,7 @@ Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<AtomicWaitExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model) { @@ -850,7 +850,7 @@ Result BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<AtomicNotifyExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnBinaryExpr(Opcode opcode) { @@ -1037,7 +1037,7 @@ Result BinaryReaderIR::OnLoadExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<LoadExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnLoopExpr(Type sig_type) { @@ -1164,7 +1164,7 @@ Result BinaryReaderIR::OnStoreExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<StoreExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnThrowExpr(Index tag_index) { @@ -1279,7 +1279,8 @@ Result BinaryReaderIR::OnSimdLoadLaneExpr(Opcode opcode, Address offset, uint64_t value) { return AppendExpr(std::make_unique<SimdLoadLaneExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset, value)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset, + value)); } Result BinaryReaderIR::OnSimdStoreLaneExpr(Opcode opcode, @@ -1288,7 +1289,8 @@ Result BinaryReaderIR::OnSimdStoreLaneExpr(Opcode opcode, Address offset, uint64_t value) { return AppendExpr(std::make_unique<SimdStoreLaneExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset, value)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset, + value)); } Result BinaryReaderIR::OnSimdShuffleOpExpr(Opcode opcode, v128 value) { @@ -1300,7 +1302,7 @@ Result BinaryReaderIR::OnLoadSplatExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<LoadSplatExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnLoadZeroExpr(Opcode opcode, @@ -1308,7 +1310,7 @@ Result BinaryReaderIR::OnLoadZeroExpr(Opcode opcode, Address alignment_log2, Address offset) { return AppendExpr(std::make_unique<LoadZeroExpr>( - opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset)); + opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset)); } Result BinaryReaderIR::OnElemSegmentCount(Index count) { diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 341e8861..ee8eed49 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -122,6 +122,8 @@ class BinaryReader { [[nodiscard]] Result ReadIndex(Index* index, const char* desc); [[nodiscard]] Result ReadOffset(Offset* offset, const char* desc); [[nodiscard]] Result ReadAlignment(Address* align_log2, const char* desc); + [[nodiscard]] Result CheckAlignment(Address* align_log2, const char* desc); + [[nodiscard]] Result TakeHasMemidx(Address* align_log2, bool* has_memidx); [[nodiscard]] Result ReadMemidx(Index* memidx, const char* desc); [[nodiscard]] Result ReadMemLocation(Address* alignment_log2, Index* memidx, @@ -432,12 +434,24 @@ Result BinaryReader::ReadOffset(Offset* offset, const char* desc) { Result BinaryReader::ReadAlignment(Address* alignment_log2, const char* desc) { uint32_t value; CHECK_RESULT(ReadU32Leb128(&value, desc)); - if (value >= 128 || - (value >= 32 && !options_.features.multi_memory_enabled())) { - PrintError("invalid %s: %u", desc, value); + *alignment_log2 = value; + return Result::Ok; +} + +Result BinaryReader::CheckAlignment(Address* align_log2, const char* desc) { + uint32_t value = *align_log2; + if (value >= 32) { + PrintError("invalid %s: %" PRIu32, desc, value); return Result::Error; } - *alignment_log2 = value; + return Result::Ok; +} + +Result BinaryReader::TakeHasMemidx(Address* align_log2, bool* has_memidx) { + // extract the has_memidx flag + *has_memidx = (*align_log2 >> 6) & 1; + // then clear it + *align_log2 &= ~(1 << 6); return Result::Ok; } @@ -453,12 +467,14 @@ Result BinaryReader::ReadMemLocation(Address* alignment_log2, const char* desc_memidx, const char* desc_offset, uint8_t* lane_val) { + bool has_memidx = false; CHECK_RESULT(ReadAlignment(alignment_log2, desc_align)); + CHECK_RESULT(TakeHasMemidx(alignment_log2, &has_memidx)); + CHECK_RESULT(CheckAlignment(alignment_log2, desc_align)); *memidx = 0; - if (*alignment_log2 >> 6) { + if (has_memidx) { ERROR_IF(!options_.features.multi_memory_enabled(), "multi_memory not allowed"); - *alignment_log2 = *alignment_log2 & ((1 << 6) - 1); CHECK_RESULT(ReadMemidx(memidx, desc_memidx)); } CHECK_RESULT(ReadAddress(offset, 0, desc_offset)); @@ -2267,6 +2283,7 @@ Result BinaryReader::ReadLinkingSection(Offset section_size) { uint32_t flags; CHECK_RESULT(ReadStr(&name, "segment name")); CHECK_RESULT(ReadAlignment(&alignment_log2, "segment alignment")); + CHECK_RESULT(CheckAlignment(&alignment_log2, "segment alignment")); CHECK_RESULT(ReadU32Leb128(&flags, "segment flags")); CALLBACK(OnSegmentInfo, i, name, alignment_log2, flags); } diff --git a/test/binary/bad-alignment.txt b/test/binary/bad-alignment.txt index 4601c27c..e975dd10 100644 --- a/test/binary/bad-alignment.txt +++ b/test/binary/bad-alignment.txt @@ -8,11 +8,12 @@ section(CODE) { count[1] func { locals[0] + i32.const leb_i32(0) i32.load align[65] offset[0] drop } } (;; STDERR ;;; -000001e: error: invalid load alignment: 65 -000001e: error: invalid load alignment: 65 +0000020: error: multi_memory not allowed +0000020: error: multi_memory not allowed ;;; STDERR ;;) diff --git a/test/regress/undefined-shifts.txt b/test/regress/undefined-shifts.txt new file mode 100644 index 00000000..6bfc3c3d --- /dev/null +++ b/test/regress/undefined-shifts.txt @@ -0,0 +1,21 @@ +;;; TOOL: run-gen-wasm-bad +;;; ARGS1: --enable-multi-memory +;;; ARGS2: --enable-multi-memory +magic +version +section(TYPE) { count[1] function params[0] results[0] } +section(FUNCTION) { count[1] type[0] } +section(MEMORY) { count[1] flags[0] min[1] } +section(CODE) { + count[1] + func { + locals[0] + i32.const leb_u32(0) + i32.load align[63] offset[0] + drop + } +} +(;; STDERR ;;; +0000020: error: invalid load alignment: 63 +0000020: error: invalid load alignment: 63 +;;; STDERR ;;) |