in Tpm2Tester/TestSubstrate/TestFuzzer.cs [1049:1195]
internal bool TransformerCallback(CommandInfo info, ref byte[] parmsBuf,
TpmHandle[] inHandles)
{
if (parmsBuf.Length == 0 && info.HandleCountIn == 0)
{
// There is no sense in fuzzing this command.
Substrate.Assert(!IsFuzzing);
SkipRawFuzzer = true;
return false;
}
TpmCc cmdCode = info.CommandCode;
TimeSpan progressPeriod = new TimeSpan(0, 0, 2);
DateTime now = DateTime.Now;
if (!FuzzedCommands.ContainsKey(cmdCode))
{
AverageCmdComplexity = AverageCmdComplexity * FuzzedCommands.Count
/ (FuzzedCommands.Count + 1);
FuzzedCommands.Add(cmdCode, new FuzzStats(info));
}
FuzzStats cmdStat = FuzzedCommands[cmdCode];
if (!IsFuzzing)
{
// We are not yet fuzzing. Start the next fuzzing series now?
if (!IsCommandSafe(cmdCode, inHandles))
{
// Fuzzing this command may get theTPM bricked
return false;
}
if (FuzzCmd == null)
{
if (cmdStat.fuzzSeries == 0)
{
Threshold = BaseFuzzProbability + (1.0 - 1.0 / (cmdStat.fuzzBypassed + 1))
* (MaxFuzzProbability - BaseFuzzProbability);
}
else
{
if (LastFuzzedCommand != cmdCode)
{
Threshold = BaseFuzzProbability;
}
else
{
// Decrease the chance of fuzzing the same command twice in a row
Threshold = MinFuzzProbability
+ Threshold * (BaseFuzzProbability - MinFuzzProbability);
}
AdjustFuzzingProbability(cmdStat);
}
}
else if (cmdCode.ToString() != FuzzCmd)
{
// Exclusive fuzzing mode: skip all commands but FuzzCmd
return false;
}
else
{
// Exclusive fuzzing mode uses a random fuzzing probability
Threshold = MinFuzzProbability
+ Globs.GetRandomDouble() * (MaxFuzzProbability - MinFuzzProbability);
}
Debug.Assert(Threshold >= MinFuzzProbability && Threshold <= MaxFuzzProbability);
if (Globs.GetRandomDouble() > Threshold)
{
++cmdStat.fuzzBypassed;
++TotalFuzzBypasses;
return false;
}
// Start fuzzing...
++TotalFuzzSeries;
++cmdStat.fuzzSeries;
AverageFuzzSeriesPerCmd = (double)TotalFuzzSeries / FuzzedCommands.Count;
IsFuzzing = true;
// Ignore test failures from this point until the end of the test case
MainTestContext.ReportErrors = false;
CurFuzzCmd = cmdCode;
CurFuzzingSeriesHadSuccesses = CurFuzzingSeriesHadFailures = false;
CurFuzzStats = new FuzzStats(info);
TimeSpan toGo = TestCfg.TestEndTime - now;
if(toGo < new TimeSpan())
{
toGo = new TimeSpan();
}
WriteToLog("Fuzzing {0} ({1} to go) ", cmdCode,
toGo.ToString(@"dd\d\ hh\:mm\:ss"), ConsoleColor.Magenta);
NextProgressReportTime = now + progressPeriod;
CurFuzzEndTime = now + MaxCommandFuzzTime;
}
Debug.Assert(CurFuzzCmd != TpmCc.None);
Debug.Assert(CurFuzzCmd == cmdCode);
try
{
if ( DoFuzzCommand(cmdStat, ref parmsBuf, inHandles)
&& SkipRawFuzzer)
{
++CurFuzzStats.tgtFuzzes;
}
else
{
++CurFuzzStats.rawFuzzes;
}
}
catch (Exception)
{
StopFuzzing("!");
throw;
}
uint fuzzCount = CurFuzzStats.tgtFuzzes + CurFuzzStats.rawFuzzes;
Debug.Assert(fuzzCount - 1 == CurFuzzStats.succeeded + CurFuzzStats.failed);
// After a while it is better to fuzz something else
if (now > CurFuzzEndTime || fuzzCount > MaxFuzzCount)
{
StopFuzzing("\\");
throw new EscapeException();
}
// Report progress
if (now > NextProgressReportTime || fuzzCount % (MaxFuzzCount / 20) == 0)
{
ReportFuzzProgress();
NextProgressReportTime = now + progressPeriod;
}
if ( FuzzCountToBreak == fuzzCount
&& (cmdCode.ToString() == BreakCmd || BreakCount == fuzzCount))
{
// Trigger debug break point
Debug.Assert("Debug break" == "");
}
return true;
}