Skip to content

Commit 20e1270

Browse files
authored
More fuzz fixes (#1021)
* validate that memory/table segment values fit in the initial range * validate that select condition should be i32
1 parent 21cb9e8 commit 20e1270

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/wasm-validator.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ struct WasmValidator : public PostWalker<WasmValidator> {
477477
void visitSelect(Select* curr) {
478478
shouldBeUnequal(curr->ifTrue->type, none, curr, "select left must be valid");
479479
shouldBeUnequal(curr->ifFalse->type, none, curr, "select right must be valid");
480+
shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "select condition must be valid");
480481
}
481482

482483
void visitDrop(Drop* curr) {
@@ -565,8 +566,19 @@ struct WasmValidator : public PostWalker<WasmValidator> {
565566
labelNames.clear();
566567
}
567568

568-
bool isConstant(Expression* curr) {
569-
return curr->is<Const>() || curr->is<GetGlobal>();
569+
bool checkOffset(Expression* curr, Address add, Address max) {
570+
if (curr->is<GetGlobal>()) return true;
571+
auto* c = curr->dynCast<Const>();
572+
if (!c) return false;
573+
uint64_t raw = c->value.getInteger();
574+
if (raw > std::numeric_limits<Address::address_t>::max()) {
575+
return false;
576+
}
577+
if (raw + uint64_t(add) > std::numeric_limits<Address::address_t>::max()) {
578+
return false;
579+
}
580+
Address offset = raw;
581+
return offset + add <= max;
570582
}
571583

572584
void visitMemory(Memory *curr) {
@@ -575,7 +587,7 @@ struct WasmValidator : public PostWalker<WasmValidator> {
575587
Index mustBeGreaterOrEqual = 0;
576588
for (auto& segment : curr->segments) {
577589
if (!shouldBeEqual(segment.offset->type, i32, segment.offset, "segment offset should be i32")) continue;
578-
shouldBeTrue(isConstant(segment.offset), segment.offset, "segment offset should be constant");
590+
shouldBeTrue(checkOffset(segment.offset, segment.data.size(), getModule()->memory.initial * Memory::kPageSize), segment.offset, "segment offset should be reasonable");
579591
Index size = segment.data.size();
580592
shouldBeTrue(size <= curr->initial * Memory::kPageSize, segment.data.size(), "segment size should fit in memory");
581593
if (segment.offset->is<Const>()) {
@@ -590,7 +602,7 @@ struct WasmValidator : public PostWalker<WasmValidator> {
590602
void visitTable(Table* curr) {
591603
for (auto& segment : curr->segments) {
592604
shouldBeEqual(segment.offset->type, i32, segment.offset, "segment offset should be i32");
593-
shouldBeTrue(isConstant(segment.offset), segment.offset, "segment offset should be constant");
605+
shouldBeTrue(checkOffset(segment.offset, segment.data.size(), getModule()->table.initial * Table::kPageSize), segment.offset, "segment offset should be reasonable");
594606
}
595607
}
596608
void visitModule(Module *curr) {

0 commit comments

Comments
 (0)