Make proto mutator deterministic.

This commit is contained in:
Bhargava Shastry 2021-04-14 13:50:54 +02:00
parent 3e4d5c9225
commit a40813299f
3 changed files with 15 additions and 12 deletions

View File

@ -142,6 +142,7 @@ if (OSSFUZZ)
../../EVMHost.cpp ../../EVMHost.cpp
YulEvmoneInterface.cpp YulEvmoneInterface.cpp
yulFuzzerCommon.cpp yulFuzzerCommon.cpp
protomutators/YulProtoMutator.cpp
) )
target_include_directories(yul_evm_diff_ossfuzz PRIVATE target_include_directories(yul_evm_diff_ossfuzz PRIVATE
/usr/include/libprotobuf-mutator /usr/include/libprotobuf-mutator

View File

@ -26,20 +26,18 @@ void MutationInfo::exitInfo()
writeLine(SaveMessageAsText(*m_protobufMsg)); writeLine(SaveMessageAsText(*m_protobufMsg));
} }
/// Initialize deterministic PRNG.
static YulRandomNumGenerator s_rand(1337);
/// Add m/sstore(0, variable) /// Add m/sstore(0, variable)
static LPMPostProcessor<Block> addStoreToZero( static LPMPostProcessor<Block> addStoreToZero(
[](Block* _message, unsigned _seed) [](Block* _message, unsigned _seed)
{ {
YPM mutator{_seed};
if (_seed % YPM::s_highIP == 0) if (_seed % YPM::s_highIP == 0)
{ {
MutationInfo m{_message, "Added store to zero"}; MutationInfo m{_message, "Added store to zero"};
auto storeStmt = new StoreFunc(); auto storeStmt = new StoreFunc();
storeStmt->set_st(YPM::EnumTypeConverter<StoreFunc_Storage>{}.enumFromSeed(s_rand())); storeStmt->set_st(YPM::EnumTypeConverter<StoreFunc_Storage>{}.enumFromSeed(mutator.prng()));
storeStmt->set_allocated_loc(YPM::litExpression(0)); 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(); auto stmt = _message->add_statements();
stmt->set_allocated_storage_func(storeStmt); stmt->set_allocated_storage_func(storeStmt);
} }
@ -76,10 +74,10 @@ struct addControlFlow
{ {
addControlFlow() addControlFlow()
{ {
function = [](T* _message, unsigned) function = [](T* _message, unsigned _seed)
{ {
MutationInfo m{_message, "Added control flow."}; MutationInfo m{_message, "Added control flow."};
YPM::addControlFlow(_message); YPM{_seed}.addControlFlow(_message);
}; };
/// Unused variable registers callback. /// Unused variable registers callback.
LPMPostProcessor<T> callback(function); LPMPostProcessor<T> callback(function);
@ -209,7 +207,7 @@ void YPM::addControlFlow(T* _msg)
static_cast<unsigned>(ControlFlowStmt::For), static_cast<unsigned>(ControlFlowStmt::For),
static_cast<unsigned>(ControlFlowStmt::Termination) static_cast<unsigned>(ControlFlowStmt::Termination)
); );
auto random = static_cast<ControlFlowStmt>(d(s_rand.m_random)); auto random = static_cast<ControlFlowStmt>(d(prng.m_random));
Statement* s = basicBlock(_msg)->add_statements(); Statement* s = basicBlock(_msg)->add_statements();
switch (random) switch (random)
{ {
@ -255,7 +253,7 @@ Block* YPM::randomBlock(ForStmt* _stmt)
static_cast<unsigned>(ForBlocks::Init), static_cast<unsigned>(ForBlocks::Init),
static_cast<unsigned>(ForBlocks::Body) static_cast<unsigned>(ForBlocks::Body)
); );
switch (static_cast<ForBlocks>(d(s_rand.m_random))) switch (static_cast<ForBlocks>(d(prng.m_random)))
{ {
case ForBlocks::Init: case ForBlocks::Init:
return _stmt->mutable_for_init(); return _stmt->mutable_for_init();

View File

@ -46,6 +46,8 @@ struct YulRandomNumGenerator
struct YulProtoMutator struct YulProtoMutator
{ {
YulProtoMutator(unsigned _seed): prng(_seed)
{}
/// @param _value: Value of the integer literal /// @param _value: Value of the integer literal
/// @returns an integer literal protobuf message initialized with /// @returns an integer literal protobuf message initialized with
/// the given value. /// the given value.
@ -96,12 +98,14 @@ struct YulProtoMutator
static constexpr unsigned s_highIP = 23; static constexpr unsigned s_highIP = 23;
/// Add control-flow statement to basic block. /// Add control-flow statement to basic block.
template <typename T> template <typename T>
static void addControlFlow(T* _msg); void addControlFlow(T* _msg);
/// Obtain basic block for statement type. /// Obtain basic block for statement type.
template <typename T> template <typename T>
static Block* basicBlock(T* _msg); Block* basicBlock(T* _msg);
/// Obtain a basic block in a for stmt uniformly /// Obtain a basic block in a for stmt uniformly
/// at random /// at random
static Block* randomBlock(ForStmt* _msg); Block* randomBlock(ForStmt* _msg);
/// Random number generator
YulRandomNumGenerator prng;
}; };
} }