summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoni L. <EnderMoneyMod@gmail.com>2024-08-09 19:29:59 -0300
committerGitHub <noreply@github.com>2024-08-09 22:29:59 +0000
commit63fefe32e7e40efe1050c1908422b29e883c0575 (patch)
tree3a4f2a56e4344e2295b6b7d7c85cde142ae050fc
parent3e826ecde1adfba5f88d10d361131405637e65a3 (diff)
downloadwabt-63fefe32e7e40efe1050c1908422b29e883c0575.tar.gz
wabt-63fefe32e7e40efe1050c1908422b29e883c0575.tar.bz2
wabt-63fefe32e7e40efe1050c1908422b29e883c0575.zip
Harden against invalid alignment (#2411)
-rw-r--r--src/binary-reader-ir.cc26
-rw-r--r--src/binary-reader.cc29
-rw-r--r--test/binary/bad-alignment.txt5
-rw-r--r--test/regress/undefined-shifts.txt21
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 ;;)