From e4ba1c02e80c402410344f1813e54946486c1c90 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Fri, 1 Nov 2019 11:36:29 +0100 Subject: [PATCH] yul proto fuzzer: Catch exception early and propagate termination reason to harness --- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 38 ++++++----------- test/tools/ossfuzz/yulFuzzerCommon.cpp | 23 +++++++++- test/tools/ossfuzz/yulFuzzerCommon.h | 10 ++++- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 42 ++++++------------- 4 files changed, 55 insertions(+), 58 deletions(-) diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index c61bf9817..5b644812c 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -78,35 +78,21 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) ostringstream os1; ostringstream os2; - try - { - yulFuzzerUtil::interpret( - os1, - stack.parserResult()->code, - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) - ); - } - catch (yul::test::StepLimitReached const&) - { + yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( + os1, + stack.parserResult()->code, + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) + ); + if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached) return 0; - } - catch (yul::test::InterpreterTerminatedGeneric const&) - { - } stack.optimize(); - try - { - yulFuzzerUtil::interpret( - os2, - stack.parserResult()->code, - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - (yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) - ); - } - catch (yul::test::InterpreterTerminatedGeneric const&) - { - } + termReason = yulFuzzerUtil::interpret( + os2, + stack.parserResult()->code, + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + (yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) + ); bool isTraceEq = (os1.str() == os2.str()); yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ."); diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index 36a2d9edc..2069582b0 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -20,7 +20,7 @@ using namespace std; using namespace yul; using namespace yul::test::yul_fuzzer; -void yulFuzzerUtil::interpret( +yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( ostream& _os, shared_ptr _ast, Dialect const& _dialect, @@ -44,6 +44,25 @@ void yulFuzzerUtil::interpret( 0x8e, 0xf3, 0x9b, 0xe4, 0x4f, 0x6c, 0x14, 0xde }; Interpreter interpreter(state, _dialect); - interpreter(*_ast); + + TerminationReason reason = TerminationReason::None; + try + { + interpreter(*_ast); + } + catch (StepLimitReached const&) + { + reason = TerminationReason::StepLimitReached; + } + catch (TraceLimitReached const&) + { + reason = TerminationReason::TraceLimitReached; + } + catch (ExplicitlyTerminated const&) + { + reason = TerminationReason::ExplicitlyTerminated; + } + state.dumpTraceAndState(_os); + return reason; } diff --git a/test/tools/ossfuzz/yulFuzzerCommon.h b/test/tools/ossfuzz/yulFuzzerCommon.h index fd48bb796..7cc0e156f 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.h +++ b/test/tools/ossfuzz/yulFuzzerCommon.h @@ -25,7 +25,15 @@ namespace yul_fuzzer { struct yulFuzzerUtil { - static void interpret( + enum class TerminationReason + { + ExplicitlyTerminated, + StepLimitReached, + TraceLimitReached, + None + }; + + static TerminationReason interpret( std::ostream& _os, std::shared_ptr _ast, Dialect const& _dialect, diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index 41cd6edab..c6ae3b368 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -66,9 +66,6 @@ DEFINE_PROTO_FUZZER(Program const& _input) of.write(yul_source.data(), yul_source.size()); } - if (yul_source.size() > 1200) - return; - YulStringRepository::reset(); // AssemblyStack entry point @@ -95,35 +92,22 @@ DEFINE_PROTO_FUZZER(Program const& _input) ostringstream os1; ostringstream os2; - try - { - yulFuzzerUtil::interpret( - os1, - stack.parserResult()->code, - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) - ); - } - catch (yul::test::StepLimitReached const&) - { + yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( + os1, + stack.parserResult()->code, + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) + ); + + if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached) return; - } - catch (yul::test::InterpreterTerminatedGeneric const&) - { - } stack.optimize(); - try - { - yulFuzzerUtil::interpret( - os2, - stack.parserResult()->code, - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - (yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) - ); - } - catch (yul::test::InterpreterTerminatedGeneric const&) - { - } + termReason = yulFuzzerUtil::interpret( + os2, + stack.parserResult()->code, + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + (yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) + ); bool isTraceEq = (os1.str() == os2.str()); yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ.");