diff --git a/test/tools/ossfuzz/CMakeLists.txt b/test/tools/ossfuzz/CMakeLists.txt index cdc412163..36a1744a4 100644 --- a/test/tools/ossfuzz/CMakeLists.txt +++ b/test/tools/ossfuzz/CMakeLists.txt @@ -142,6 +142,7 @@ if (OSSFUZZ) ../../EVMHost.cpp YulEvmoneInterface.cpp yulFuzzerCommon.cpp + protomutators/YulProtoMutator.cpp ) target_include_directories(yul_evm_diff_ossfuzz PRIVATE /usr/include/libprotobuf-mutator diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp index b96d0b144..572064faa 100644 --- a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp @@ -26,20 +26,18 @@ void MutationInfo::exitInfo() writeLine(SaveMessageAsText(*m_protobufMsg)); } -/// Initialize deterministic PRNG. -static YulRandomNumGenerator s_rand(1337); - /// Add m/sstore(0, variable) static LPMPostProcessor addStoreToZero( [](Block* _message, unsigned _seed) { + YPM mutator{_seed}; if (_seed % YPM::s_highIP == 0) { MutationInfo m{_message, "Added store to zero"}; auto storeStmt = new StoreFunc(); - storeStmt->set_st(YPM::EnumTypeConverter{}.enumFromSeed(s_rand())); + storeStmt->set_st(YPM::EnumTypeConverter{}.enumFromSeed(mutator.prng())); storeStmt->set_allocated_loc(YPM::litExpression(0)); - storeStmt->set_allocated_val(YPM::refExpression(s_rand)); + storeStmt->set_allocated_val(YPM::refExpression(mutator.prng)); auto stmt = _message->add_statements(); stmt->set_allocated_storage_func(storeStmt); } @@ -76,10 +74,10 @@ struct addControlFlow { addControlFlow() { - function = [](T* _message, unsigned) + function = [](T* _message, unsigned _seed) { MutationInfo m{_message, "Added control flow."}; - YPM::addControlFlow(_message); + YPM{_seed}.addControlFlow(_message); }; /// Unused variable registers callback. LPMPostProcessor callback(function); @@ -209,7 +207,7 @@ void YPM::addControlFlow(T* _msg) static_cast(ControlFlowStmt::For), static_cast(ControlFlowStmt::Termination) ); - auto random = static_cast(d(s_rand.m_random)); + auto random = static_cast(d(prng.m_random)); Statement* s = basicBlock(_msg)->add_statements(); switch (random) { @@ -255,7 +253,7 @@ Block* YPM::randomBlock(ForStmt* _stmt) static_cast(ForBlocks::Init), static_cast(ForBlocks::Body) ); - switch (static_cast(d(s_rand.m_random))) + switch (static_cast(d(prng.m_random))) { case ForBlocks::Init: return _stmt->mutable_for_init(); diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.h b/test/tools/ossfuzz/protomutators/YulProtoMutator.h index e947a61c3..7d2c9c794 100644 --- a/test/tools/ossfuzz/protomutators/YulProtoMutator.h +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.h @@ -46,6 +46,8 @@ struct YulRandomNumGenerator struct YulProtoMutator { + YulProtoMutator(unsigned _seed): prng(_seed) + {} /// @param _value: Value of the integer literal /// @returns an integer literal protobuf message initialized with /// the given value. @@ -96,12 +98,14 @@ struct YulProtoMutator static constexpr unsigned s_highIP = 23; /// Add control-flow statement to basic block. template - static void addControlFlow(T* _msg); + void addControlFlow(T* _msg); /// Obtain basic block for statement type. template - static Block* basicBlock(T* _msg); + Block* basicBlock(T* _msg); /// Obtain a basic block in a for stmt uniformly /// at random - static Block* randomBlock(ForStmt* _msg); + Block* randomBlock(ForStmt* _msg); + /// Random number generator + YulRandomNumGenerator prng; }; }