From 9544df34d70dc99f43819e957d5c2d1e2c527b5e Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Fri, 28 Feb 2020 12:48:59 +0100 Subject: [PATCH] solc fuzzers: Use compiler stack for fuzzing --- test/tools/afl_fuzzer.cpp | 2 +- test/tools/fuzzer_common.cpp | 99 +++++++++++++++-------- test/tools/fuzzer_common.h | 3 +- test/tools/ossfuzz/solc_noopt_ossfuzz.cpp | 2 +- test/tools/ossfuzz/solc_opt_ossfuzz.cpp | 2 +- 5 files changed, 72 insertions(+), 36 deletions(-) diff --git a/test/tools/afl_fuzzer.cpp b/test/tools/afl_fuzzer.cpp index 1ca5428e1..eff4bc55a 100644 --- a/test/tools/afl_fuzzer.cpp +++ b/test/tools/afl_fuzzer.cpp @@ -124,7 +124,7 @@ Allowed options)", else if (arguments.count("standard-json")) FuzzerUtil::testStandardCompiler(input, quiet); else - FuzzerUtil::testCompiler(input, optimize, quiet); + FuzzerUtil::testCompilerJsonInterface(input, optimize, quiet); } catch (...) { diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index f66c2e841..e4de0f185 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -17,28 +17,87 @@ #include +#include + #include + #include #include + #include +#include + #include using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::evmasm; +using namespace solidity::langutil; -static vector s_evmVersions = { - "homestead", - "tangerineWhistle", - "spuriousDragon", - "byzantium", - "constantinople", - "petersburg", - "istanbul" +static vector s_evmVersions = { + EVMVersion::homestead(), + EVMVersion::tangerineWhistle(), + EVMVersion::spuriousDragon(), + EVMVersion::byzantium(), + EVMVersion::constantinople(), + EVMVersion::petersburg(), + EVMVersion::istanbul(), + EVMVersion::berlin() }; +void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize, bool _quiet) +{ + if (!_quiet) + cout << "Testing compiler " << (_optimize ? "with" : "without") << " optimizer." << endl; + + Json::Value config = Json::objectValue; + config["language"] = "Solidity"; + config["sources"] = Json::objectValue; + config["sources"][""] = Json::objectValue; + config["sources"][""]["content"] = _input; + config["settings"] = Json::objectValue; + config["settings"]["optimizer"] = Json::objectValue; + config["settings"]["optimizer"]["enabled"] = _optimize; + config["settings"]["optimizer"]["runs"] = 200; + config["settings"]["evmVersion"] = "berlin"; + + // Enable all SourceUnit-level outputs. + config["settings"]["outputSelection"]["*"][""][0] = "*"; + // Enable all Contract-level outputs. + config["settings"]["outputSelection"]["*"]["*"][0] = "*"; + + runCompiler(jsonCompactPrint(config), _quiet); +} + +void FuzzerUtil::testCompiler(string const& _input, bool _optimize) +{ + frontend::CompilerStack compiler; + EVMVersion evmVersion = s_evmVersions[_input.size() % s_evmVersions.size()]; + frontend::OptimiserSettings optimiserSettings; + if (_optimize) + optimiserSettings = frontend::OptimiserSettings::standard(); + else + optimiserSettings = frontend::OptimiserSettings::minimal(); + compiler.setSources({{"", _input}}); + compiler.setEVMVersion(evmVersion); + compiler.setOptimiserSettings(optimiserSettings); + try + { + compiler.compile(); + } + catch (Error const&) + { + } + catch (FatalError const&) + { + } + catch (UnimplementedFeatureError const&) + { + } +} + void FuzzerUtil::runCompiler(string const& _input, bool _quiet) { if (!_quiet) @@ -73,30 +132,6 @@ void FuzzerUtil::runCompiler(string const& _input, bool _quiet) } } -void FuzzerUtil::testCompiler(string const& _input, bool _optimize, bool _quiet) -{ - if (!_quiet) - cout << "Testing compiler " << (_optimize ? "with" : "without") << " optimizer." << endl; - - Json::Value config = Json::objectValue; - config["language"] = "Solidity"; - config["sources"] = Json::objectValue; - config["sources"][""] = Json::objectValue; - config["sources"][""]["content"] = _input; - config["settings"] = Json::objectValue; - config["settings"]["optimizer"] = Json::objectValue; - config["settings"]["optimizer"]["enabled"] = _optimize; - config["settings"]["optimizer"]["runs"] = 200; - config["settings"]["evmVersion"] = s_evmVersions[_input.size() % s_evmVersions.size()]; - - // Enable all SourceUnit-level outputs. - config["settings"]["outputSelection"]["*"][""][0] = "*"; - // Enable all Contract-level outputs. - config["settings"]["outputSelection"]["*"]["*"][0] = "*"; - - runCompiler(jsonCompactPrint(config), _quiet); -} - void FuzzerUtil::testConstantOptimizer(string const& _input, bool _quiet) { if (!_quiet) diff --git a/test/tools/fuzzer_common.h b/test/tools/fuzzer_common.h index edf196c1c..801c8c1c1 100644 --- a/test/tools/fuzzer_common.h +++ b/test/tools/fuzzer_common.h @@ -24,7 +24,8 @@ struct FuzzerUtil { static void runCompiler(std::string const& _input, bool _quiet); - static void testCompiler(std::string const& _input, bool _optimize, bool _quiet); + static void testCompilerJsonInterface(std::string const& _input, bool _optimize, bool _quiet); static void testConstantOptimizer(std::string const& _input, bool _quiet); static void testStandardCompiler(std::string const& _input, bool _quiet); + static void testCompiler(std::string const& _input, bool _optimize); }; diff --git a/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp b/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp index 3a2ac5f27..efed3769f 100644 --- a/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp +++ b/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp @@ -24,7 +24,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) if (_size <= 600) { string input(reinterpret_cast(_data), _size); - FuzzerUtil::testCompiler(input, /*optimize=*/false, /*quiet=*/true); + FuzzerUtil::testCompiler(input, /*optimize=*/false); } return 0; } diff --git a/test/tools/ossfuzz/solc_opt_ossfuzz.cpp b/test/tools/ossfuzz/solc_opt_ossfuzz.cpp index 72a59cba4..fc431ffe5 100644 --- a/test/tools/ossfuzz/solc_opt_ossfuzz.cpp +++ b/test/tools/ossfuzz/solc_opt_ossfuzz.cpp @@ -24,7 +24,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) if (_size <= 600) { string input(reinterpret_cast(_data), _size); - FuzzerUtil::testCompiler(input, /*optimize=*/true, /*quiet=*/true); + FuzzerUtil::testCompiler(input, /*optimize=*/true); } return 0; }