diff --git a/test/tools/ossfuzz/CMakeLists.txt b/test/tools/ossfuzz/CMakeLists.txt index 83543b9f0..0e4c1456a 100644 --- a/test/tools/ossfuzz/CMakeLists.txt +++ b/test/tools/ossfuzz/CMakeLists.txt @@ -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 diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp new file mode 100644 index 000000000..4765ccd7f --- /dev/null +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp @@ -0,0 +1,150 @@ +#include + +#include + +#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(_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(_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(_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(_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(_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 + } + } + } +); \ No newline at end of file diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.h b/test/tools/ossfuzz/protomutators/YulProtoMutator.h new file mode 100644 index 000000000..ed2798449 --- /dev/null +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include + +namespace yul +{ +namespace test +{ +namespace yul_fuzzer +{ +struct YulProtoMutator +{ + YulProtoMutator( + google::protobuf::Descriptor const* _desc, + std::function _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; +}; + + + +} +} +} \ No newline at end of file