diff options
author | Alon Zakai <alonzakai@gmail.com> | 2018-03-06 10:21:48 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-06 10:21:48 -0800 |
commit | e8b75397304ca6d6c2ef87217df07e697248a576 (patch) | |
tree | 7da3e3f94b5cd74e969bc529181a8b8d29dfcf8c /src | |
parent | e5dd0fdfc554be665cbe586fbbe4f9d038f5b9d6 (diff) | |
download | binaryen-e8b75397304ca6d6c2ef87217df07e697248a576.tar.gz binaryen-e8b75397304ca6d6c2ef87217df07e697248a576.tar.bz2 binaryen-e8b75397304ca6d6c2ef87217df07e697248a576.zip |
afl-fuzz fixes for table/memory instantiation (#1460)
* replace assert with a proper trap for an invalid offset in table initialization
* fix offset handling in initial table size computation: it is an unsigned value
* handle traps in fuzz-exec when creating instance
* optimization may remove imports - and imported table init may trap, so opts may remove that trap. check for result comparisons in the right order, so we don't get bothered by that
Diffstat (limited to 'src')
-rw-r--r-- | src/shell-interface.h | 12 | ||||
-rw-r--r-- | src/tools/execution-results.h | 34 |
2 files changed, 27 insertions, 19 deletions
diff --git a/src/shell-interface.h b/src/shell-interface.h index e41d9de24..0a98ce05a 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -95,8 +95,10 @@ struct ShellExternalInterface final : ModuleInstance::ExternalInterface { memory.resize(wasm.memory.initial * wasm::Memory::kPageSize); // apply memory segments for (auto& segment : wasm.memory.segments) { - Address offset = ConstantExpressionRunner<TrivialGlobalManager>(instance.globals).visit(segment.offset).value.geti32(); - assert(offset + segment.data.size() <= wasm.memory.initial * wasm::Memory::kPageSize); + Address offset = (uint32_t)ConstantExpressionRunner<TrivialGlobalManager>(instance.globals).visit(segment.offset).value.geti32(); + if (offset + segment.data.size() > wasm.memory.initial * wasm::Memory::kPageSize) { + trap("invalid offset when initializing memory"); + } for (size_t i = 0; i != segment.data.size(); ++i) { memory.set(offset + i, segment.data[i]); } @@ -104,8 +106,10 @@ struct ShellExternalInterface final : ModuleInstance::ExternalInterface { table.resize(wasm.table.initial); for (auto& segment : wasm.table.segments) { - Address offset = ConstantExpressionRunner<TrivialGlobalManager>(instance.globals).visit(segment.offset).value.geti32(); - assert(offset + segment.data.size() <= wasm.table.initial); + Address offset = (uint32_t)ConstantExpressionRunner<TrivialGlobalManager>(instance.globals).visit(segment.offset).value.geti32(); + if (offset + segment.data.size() > wasm.table.initial) { + trap("invalid offset when initializing table"); + } for (size_t i = 0; i != segment.data.size(); ++i) { table[offset + i] = segment.data[i]; } diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 7537d9911..fe82c024a 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -37,20 +37,24 @@ struct ExecutionResults { return; } ShellExternalInterface interface; - ModuleInstance instance(wasm, &interface); - // execute all exported methods (that are therefore preserved through opts) - for (auto& exp : wasm.exports) { - if (exp->kind != ExternalKind::Function) continue; - auto* func = wasm.getFunction(exp->value); - if (func->result != none) { - // this has a result - results[exp->name] = run(func, wasm, instance); - std::cout << "[fuzz-exec] note result: " << exp->name << " => " << results[exp->name] << '\n'; - } else { - // no result, run it anyhow (it might modify memory etc.) - run(func, wasm, instance); - std::cout << "[fuzz-exec] no result for void func: " << exp->name << '\n'; + try { + ModuleInstance instance(wasm, &interface); + // execute all exported methods (that are therefore preserved through opts) + for (auto& exp : wasm.exports) { + if (exp->kind != ExternalKind::Function) continue; + auto* func = wasm.getFunction(exp->value); + if (func->result != none) { + // this has a result + results[exp->name] = run(func, wasm, instance); + std::cout << "[fuzz-exec] note result: " << exp->name << " => " << results[exp->name] << '\n'; + } else { + // no result, run it anyhow (it might modify memory etc.) + run(func, wasm, instance); + std::cout << "[fuzz-exec] no result for void func: " << exp->name << '\n'; + } } + } catch (const TrapException&) { + // may throw in instance creation (init of offsets) } std::cout << "[fuzz-exec] " << results.size() << " results noted\n"; } @@ -67,9 +71,9 @@ struct ExecutionResults { } bool operator==(ExecutionResults& other) { - for (auto& iter : results) { + for (auto& iter : other.results) { auto name = iter.first; - if (other.results.find(name) == other.results.end()) { + if (results.find(name) == results.end()) { std::cout << "[fuzz-exec] missing " << name << '\n'; abort(); } |