feat(fuzz): add SharpFuzz-based fuzzing for untrusted-input parsers
New tests/PalladiumWallet.Fuzz project: one target per parser that consumes untrusted input (block headers, Merkle proofs, peer lists, wallet files, user-pasted mnemonics/keys/addresses/amounts), each encoding the parser's documented error contract - any exception beyond that contract is a finding, reported as a crash. Three ways to run: the seed corpus (with regression inputs for every crash found so far, including the two fixed in prior commits) replays automatically inside dotnet test via FuzzCorpusTests, so a fixed contract violation can't silently return; a built-in random-mutation mode needs no external tooling (dotnet run -- <target> --random N); and fuzz.sh drives real coverage-guided campaigns via afl++ + SharpFuzz instrumentation for pre-release or post-parser-change runs.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using PalladiumWallet.Fuzz;
|
||||
|
||||
namespace PalladiumWallet.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Replays the fuzzing seed corpus (tests/PalladiumWallet.Fuzz/Corpus, copied
|
||||
/// next to the test binary) through every fuzz target on each test run: the
|
||||
/// corpus includes the regression inputs for crashes found by past campaigns,
|
||||
/// so a fixed contract violation can never silently come back. The real
|
||||
/// coverage-guided campaigns run separately via tests/PalladiumWallet.Fuzz/fuzz.sh.
|
||||
/// </summary>
|
||||
public class FuzzCorpusTests
|
||||
{
|
||||
public static TheoryData<string> Targets()
|
||||
{
|
||||
var data = new TheoryData<string>();
|
||||
foreach (var name in FuzzTargets.All.Keys)
|
||||
data.Add(name);
|
||||
return data;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(Targets))]
|
||||
public void Il_corpus_del_target_rispetta_il_contratto_del_parser(string target)
|
||||
{
|
||||
var dir = Path.Combine(AppContext.BaseDirectory, "Corpus", target);
|
||||
Assert.True(Directory.Exists(dir), $"seed corpus missing for '{target}' at {dir}");
|
||||
|
||||
foreach (var file in Directory.EnumerateFiles(dir))
|
||||
{
|
||||
// Any escaping exception is a contract violation: the target itself
|
||||
// swallows the exception types documented as the parser's failure mode.
|
||||
FuzzTargets.Run(target, File.ReadAllBytes(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user