mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
yul fuzzer: Add custom mutation routines
This commit is contained in:
parent
e32bb74b30
commit
ec56c785c1
@ -10,7 +10,11 @@ add_dependencies(ossfuzz
|
||||
|
||||
if (OSSFUZZ)
|
||||
add_custom_target(ossfuzz_proto)
|
||||
add_dependencies(ossfuzz_proto yul_proto_ossfuzz yul_proto_diff_ossfuzz)
|
||||
add_dependencies(ossfuzz_proto
|
||||
yul_proto_ossfuzz
|
||||
yul_proto_diff_ossfuzz
|
||||
yul_proto_diff_custom_mutate_ossfuzz
|
||||
)
|
||||
|
||||
add_custom_target(ossfuzz_abiv2)
|
||||
add_dependencies(ossfuzz_abiv2 abiv2_proto_ossfuzz)
|
||||
@ -60,6 +64,22 @@ if (OSSFUZZ)
|
||||
)
|
||||
set_target_properties(yul_proto_diff_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(yul_proto_diff_custom_mutate_ossfuzz
|
||||
yulProto_diff_ossfuzz.cpp
|
||||
yulFuzzerCommon.cpp
|
||||
protoToYul.cpp
|
||||
yulProto.pb.cc
|
||||
protomutators/YulProtoMutator.cpp
|
||||
)
|
||||
target_include_directories(yul_proto_diff_custom_mutate_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
||||
target_link_libraries(yul_proto_diff_custom_mutate_ossfuzz PRIVATE yul
|
||||
yulInterpreter
|
||||
protobuf-mutator-libfuzzer.a
|
||||
protobuf-mutator.a
|
||||
protobuf.a
|
||||
)
|
||||
set_target_properties(yul_proto_diff_custom_mutate_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(abiv2_proto_ossfuzz
|
||||
../../EVMHost.cpp
|
||||
abiV2ProtoFuzzer.cpp
|
||||
|
150
test/tools/ossfuzz/protomutators/YulProtoMutator.cpp
Normal file
150
test/tools/ossfuzz/protomutators/YulProtoMutator.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include <test/tools/ossfuzz/protomutators/YulProtoMutator.h>
|
||||
|
||||
#include <src/text_format.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
using namespace yul::test::yul_fuzzer;
|
||||
|
||||
/// Invert condition of an if statement
|
||||
static YulProtoMutator invertIfCondition(
|
||||
IfStmt::descriptor(),
|
||||
[](google::protobuf::Message* _message, unsigned int _seed)
|
||||
{
|
||||
IfStmt* ifStmt = static_cast<IfStmt*>(_message);
|
||||
if (_seed % YulProtoMutator::s_mediumIP == 0)
|
||||
{
|
||||
if (ifStmt->has_cond())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "YULMUTATOR: If condition inverted" << std::endl;
|
||||
#endif
|
||||
UnaryOp* notOp = new UnaryOp();
|
||||
notOp->set_op(UnaryOp::NOT);
|
||||
Expression *oldCond = ifStmt->release_cond();
|
||||
notOp->set_allocated_operand(oldCond);
|
||||
Expression *ifCond = new Expression();
|
||||
ifCond->set_allocated_unop(notOp);
|
||||
ifStmt->set_allocated_cond(ifCond);
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Add break statement in body of a for-loop statement
|
||||
static YulProtoMutator addBreak(
|
||||
ForStmt::descriptor(),
|
||||
[](google::protobuf::Message* _message, unsigned int _seed)
|
||||
{
|
||||
ForStmt* forStmt = static_cast<ForStmt*>(_message);
|
||||
if (_seed % YulProtoMutator::s_mediumIP == 0)
|
||||
{
|
||||
if (forStmt->has_for_body())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "YULMUTATOR: Break added" << std::endl;
|
||||
#endif
|
||||
BreakStmt* breakStmt = new BreakStmt();
|
||||
Statement* statement = forStmt->mutable_for_body()->add_statements();
|
||||
statement->clear_stmt_oneof();
|
||||
statement->set_allocated_breakstmt(breakStmt);
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Add break statement in body of a for-loop statement
|
||||
static YulProtoMutator addContinue(
|
||||
ForStmt::descriptor(),
|
||||
[](google::protobuf::Message* _message, unsigned int _seed)
|
||||
{
|
||||
ForStmt* forStmt = static_cast<ForStmt*>(_message);
|
||||
if (_seed % YulProtoMutator::s_mediumIP == 0)
|
||||
{
|
||||
if (forStmt->has_for_body())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "YULMUTATOR: Continue added" << std::endl;
|
||||
#endif
|
||||
ContinueStmt* contStmt = new ContinueStmt();
|
||||
Statement* statement = forStmt->mutable_for_body()->add_statements();
|
||||
statement->clear_stmt_oneof();
|
||||
statement->set_allocated_contstmt(contStmt);
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Add declaration statement referencing mload(0)
|
||||
static YulProtoMutator addMloadZero(
|
||||
VarDecl::descriptor(),
|
||||
[](google::protobuf::Message* _message, unsigned int _seed)
|
||||
{
|
||||
VarDecl* varDeclStmt = static_cast<VarDecl*>(_message);
|
||||
if (_seed % YulProtoMutator::s_mediumIP == 0)
|
||||
{
|
||||
if (varDeclStmt->has_expr())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "YULMUTATOR: mload added" << std::endl;
|
||||
#endif
|
||||
varDeclStmt->clear_expr();
|
||||
Literal *zeroLit = new Literal();
|
||||
zeroLit->set_intval(0);
|
||||
Expression *consExpr = new Expression();
|
||||
consExpr->set_allocated_cons(zeroLit);
|
||||
UnaryOp *mloadOp = new UnaryOp();
|
||||
mloadOp->set_op(UnaryOp::MLOAD);
|
||||
mloadOp->set_allocated_operand(consExpr);
|
||||
Expression *mloadExpr = new Expression();
|
||||
mloadExpr->set_allocated_unop(mloadOp);
|
||||
varDeclStmt->set_allocated_expr(mloadExpr);
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Invert condition of a for statement
|
||||
static YulProtoMutator invertForCondition(
|
||||
ForStmt::descriptor(),
|
||||
[](google::protobuf::Message* _message, unsigned int _seed)
|
||||
{
|
||||
ForStmt* forStmt = static_cast<ForStmt*>(_message);
|
||||
if (_seed % YulProtoMutator::s_mediumIP == 0)
|
||||
{
|
||||
if (forStmt->has_for_cond())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
std::cout << "YULMUTATOR: For condition inverted" << std::endl;
|
||||
#endif
|
||||
UnaryOp* notOp = new UnaryOp();
|
||||
notOp->set_op(UnaryOp::NOT);
|
||||
Expression *oldCond = forStmt->release_for_cond();
|
||||
notOp->set_allocated_operand(oldCond);
|
||||
Expression *forCond = new Expression();
|
||||
forCond->set_allocated_unop(notOp);
|
||||
forStmt->set_allocated_for_cond(forCond);
|
||||
#ifdef DEBUG
|
||||
// std::cout << protobuf_mutator::SaveMessageAsText(*_message) << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
32
test/tools/ossfuzz/protomutators/YulProtoMutator.h
Normal file
32
test/tools/ossfuzz/protomutators/YulProtoMutator.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <test/tools/ossfuzz/yulProto.pb.h>
|
||||
|
||||
#include <src/libfuzzer/libfuzzer_macro.h>
|
||||
|
||||
namespace yul
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
namespace yul_fuzzer
|
||||
{
|
||||
struct YulProtoMutator
|
||||
{
|
||||
YulProtoMutator(
|
||||
google::protobuf::Descriptor const* _desc,
|
||||
std::function<void(google::protobuf::Message*, unsigned int)> _callback
|
||||
)
|
||||
{
|
||||
protobuf_mutator::libfuzzer::RegisterPostProcessor(_desc, _callback);
|
||||
}
|
||||
|
||||
static constexpr unsigned s_lowIP = 41;
|
||||
static constexpr unsigned s_mediumIP = 29;
|
||||
static constexpr unsigned s_highIP = 17;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user