From 5beebc6b249c6393e0dbf69f0ec2374eca5d387b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 22 May 2023 12:35:23 -0700 Subject: [PATCH] Fuzzer: Limit ArrayNew sizes most of the time (#5738) --- src/tools/fuzzing/fuzzing.cpp | 13 +++- ...e-to-fuzz_all-features_metrics_noprint.txt | 73 ++++++++----------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index cfc0d9ed81c..54ff3533b3a 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -703,14 +703,23 @@ Function* TranslateToFuzzReader::addFunction() { void TranslateToFuzzReader::addHangLimitChecks(Function* func) { // loop limit - FindAll loops(func->body); - for (auto* loop : loops.list) { + for (auto* loop : FindAll(func->body).list) { loop->body = builder.makeSequence(makeHangLimitCheck(), loop->body, loop->type); } // recursion limit func->body = builder.makeSequence(makeHangLimitCheck(), func->body, func->getResults()); + // ArrayNew can hang the fuzzer if the array size is massive. This doesn't + // cause an OOM (which the fuzzer knows how to ignore) but it just works for + // many seconds on building the array. To avoid that, limit the size with high + // probability. + for (auto* arrayNew : FindAll(func->body).list) { + if (!oneIn(100)) { + arrayNew->size = builder.makeBinary( + AndInt32, arrayNew->size, builder.makeConst(int32_t(1024 - 1))); + } + } } void TranslateToFuzzReader::recombine(Function* func) { diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index b82f34f2039..8609159bc88 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,55 +1,44 @@ total - [exports] : 4 - [funcs] : 7 + [exports] : 3 + [funcs] : 11 [globals] : 16 [imports] : 5 [memories] : 1 [memory-data] : 20 - [table-data] : 0 + [table-data] : 2 [tables] : 1 [tags] : 0 - [total] : 600 - [vars] : 17 + [total] : 549 + [vars] : 49 + ArrayCopy : 1 ArrayFill : 1 - ArrayLen : 3 - ArrayNew : 12 + ArrayLen : 1 + ArrayNew : 14 ArrayNewFixed : 2 - ArraySet : 2 - AtomicCmpxchg : 1 - AtomicFence : 1 - AtomicNotify : 1 - AtomicRMW : 2 - Binary : 73 + Binary : 75 Block : 51 - Break : 5 - Call : 10 - CallRef : 3 - Const : 162 - DataDrop : 1 - Drop : 1 - GlobalGet : 21 - GlobalSet : 20 - I31Get : 1 + Break : 6 + Call : 5 + Const : 136 + Drop : 2 + GlobalGet : 24 + GlobalSet : 24 I31New : 4 - If : 21 - Load : 22 - LocalGet : 43 - LocalSet : 29 - Loop : 4 - MemoryFill : 1 + If : 16 + Load : 18 + LocalGet : 54 + LocalSet : 31 + Loop : 2 Nop : 8 - RefAs : 5 - RefCast : 2 - RefEq : 2 - RefFunc : 9 - RefIsNull : 4 - RefNull : 8 - RefTest : 2 - Return : 6 - Select : 2 - Store : 2 - StructNew : 18 - TupleExtract : 2 + RefAs : 3 + RefFunc : 4 + RefNull : 10 + Return : 1 + SIMDExtract : 1 + Select : 1 + StructGet : 2 + StructNew : 16 + TupleExtract : 3 TupleMake : 4 - Unary : 19 - Unreachable : 10 + Unary : 17 + Unreachable : 12