Make proto mutator deterministic.

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

View File

@ -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

View File

@ -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<Block> 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<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_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<T> callback(function);
@ -209,7 +207,7 @@ void YPM::addControlFlow(T* _msg)
static_cast<unsigned>(ControlFlowStmt::For),
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();
switch (random)
{
@ -255,7 +253,7 @@ Block* YPM::randomBlock(ForStmt* _stmt)
static_cast<unsigned>(ForBlocks::Init),
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:
return _stmt->mutable_for_init();

View File

@ -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 <typename T>
static void addControlFlow(T* _msg);
void addControlFlow(T* _msg);
/// Obtain basic block for statement type.
template <typename T>
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;
};
}