Yul interpreter: Add flag to disable memory tracing and dump for fuzzing.

Model revert in yul interpreter.
Add logTrace for a few more instructions and clear trace on revert.
This commit is contained in:
Bhargava Shastry
2022-01-04 11:56:27 +01:00
parent 13723fe2bf
commit b8ad2b2718
11 changed files with 158 additions and 50 deletions
@@ -81,10 +81,15 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
ostringstream os1;
ostringstream os2;
// Disable memory tracing to avoid false positive reports
// such as unused write to memory e.g.,
// { mstore(0, 1) }
// that would be removed by the redundant store eliminator.
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
os1,
stack.parserResult()->code,
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion())
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
/*disableMemoryTracing=*/true
);
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
return 0;
@@ -93,7 +98,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
termReason = yulFuzzerUtil::interpret(
os2,
stack.parserResult()->code,
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion())
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
/*disableMemoryTracing=*/true
);
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
+3 -2
View File
@@ -26,6 +26,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
ostream& _os,
shared_ptr<yul::Block> _ast,
Dialect const& _dialect,
bool _disableMemoryTracing,
bool _outputStorageOnly,
size_t _maxSteps,
size_t _maxTraceSize,
@@ -52,7 +53,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
TerminationReason reason = TerminationReason::None;
try
{
Interpreter::run(state, _dialect, *_ast);
Interpreter::run(state, _dialect, *_ast, _disableMemoryTracing);
}
catch (StepLimitReached const&)
{
@@ -74,7 +75,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
if (_outputStorageOnly)
state.dumpStorage(_os);
else
state.dumpTraceAndState(_os);
state.dumpTraceAndState(_os, _disableMemoryTracing);
return reason;
}
+7
View File
@@ -32,10 +32,17 @@ struct yulFuzzerUtil
None
};
/// Interprets the Yul AST pointed to by @param _ast. Flag @param _outputStorageOnly
/// (unset by default) outputs an execution trace of both memory and storage;
/// if set, only storage contents are output as part of the execution trace. The
/// latter avoids false positives that will be produced by the fuzzer when certain
/// optimizer steps are activated e.g., Redundant store eliminator, Equal store
/// eliminator.
static TerminationReason interpret(
std::ostream& _os,
std::shared_ptr<yul::Block> _ast,
Dialect const& _dialect,
bool _disableMemoryTracing = false,
bool _outputStorageOnly = false,
size_t _maxSteps = maxSteps,
size_t _maxTraceSize = maxTraceSize,
+14 -3
View File
@@ -88,10 +88,15 @@ DEFINE_PROTO_FUZZER(Program const& _input)
ostringstream os1;
ostringstream os2;
// Disable memory tracing to avoid false positive reports
// such as unused write to memory e.g.,
// { mstore(0, 1) }
// that would be removed by the redundant store eliminator.
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
os1,
stack.parserResult()->code,
EVMDialect::strictAssemblyForEVMObjects(version)
EVMDialect::strictAssemblyForEVMObjects(version),
/*disableMemoryTracing=*/true
);
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
@@ -107,12 +112,18 @@ DEFINE_PROTO_FUZZER(Program const& _input)
termReason = yulFuzzerUtil::interpret(
os2,
astBlock,
EVMDialect::strictAssemblyForEVMObjects(version)
EVMDialect::strictAssemblyForEVMObjects(version),
true
);
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
return;
bool isTraceEq = (os1.str() == os2.str());
yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ.");
if (!isTraceEq)
{
cout << os1.str() << endl;
cout << os2.str() << endl;
yulAssert(false, "Interpreted traces for optimized and unoptimized code differ.");
}
return;
}