diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2021-10-19 08:54:31 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-19 11:07:51 +0200 |
commit | 387398baff2e3f37b2fa25a5f3c85a0c9b925e9e (patch) | |
tree | 6eebc2a2f938eeef927f46886a5000d1626f440f /driver | |
parent | fab033324a64a4e02e638cc6c7b243fba1846f61 (diff) | |
download | jazzer-api-387398baff2e3f37b2fa25a5f3c85a0c9b925e9e.tar.gz |
Prevent early libFuzzer exits by replaying initial coverage for two runs
Diffstat (limited to 'driver')
-rw-r--r-- | driver/coverage_tracker.cpp | 12 | ||||
-rw-r--r-- | driver/coverage_tracker.h | 1 | ||||
-rw-r--r-- | driver/fuzz_target_runner.cpp | 12 |
3 files changed, 24 insertions, 1 deletions
diff --git a/driver/coverage_tracker.cpp b/driver/coverage_tracker.cpp index e106b286..0a576085 100644 --- a/driver/coverage_tracker.cpp +++ b/driver/coverage_tracker.cpp @@ -165,6 +165,18 @@ void CoverageTracker::RecordInitialCoverage(JNIEnv &env) { AssertNoException(env); } +void CoverageTracker::ReplayInitialCoverage(JNIEnv &env) { + jclass coverage_recorder = env.FindClass(kCoverageRecorderClass); + AssertNoException(env); + jmethodID coverage_recorder_update_covered_ids_with_coverage_map = + env.GetStaticMethodID(coverage_recorder, "replayCoveredIds", "()V"); + AssertNoException(env); + env.CallStaticVoidMethod( + coverage_recorder, + coverage_recorder_update_covered_ids_with_coverage_map); + AssertNoException(env); +} + std::string CoverageTracker::ComputeCoverage(JNIEnv &env) { uintptr_t *covered_pcs; size_t num_covered_pcs = __sanitizer_cov_get_observed_pcs(&covered_pcs); diff --git a/driver/coverage_tracker.h b/driver/coverage_tracker.h index 5461fe8a..5b237de3 100644 --- a/driver/coverage_tracker.h +++ b/driver/coverage_tracker.h @@ -52,6 +52,7 @@ class CoverageTracker : public ExceptionPrinter { static uint8_t *GetCoverageCounters(); static void RecordInitialCoverage(JNIEnv &env); + static void ReplayInitialCoverage(JNIEnv &env); static std::string ComputeCoverage(JNIEnv &env); }; } // namespace jazzer diff --git a/driver/fuzz_target_runner.cpp b/driver/fuzz_target_runner.cpp index 50e317cf..230b838d 100644 --- a/driver/fuzz_target_runner.cpp +++ b/driver/fuzz_target_runner.cpp @@ -216,7 +216,7 @@ FuzzTargetRunner::FuzzTargetRunner( std::exit(1); } - if (FLAGS_hooks && !FLAGS_coverage_report.empty()) { + if (FLAGS_hooks) { CoverageTracker::RecordInitialCoverage(env); } SetUpFuzzedDataProvider(jvm_.GetEnv()); @@ -258,6 +258,16 @@ FuzzTargetRunner::~FuzzTargetRunner() { RunResult FuzzTargetRunner::Run(const uint8_t *data, const std::size_t size) { auto &env = jvm_.GetEnv(); + static std::size_t run_count = 0; + if (run_count < 2) { + run_count++; + // For the first two runs only, replay the coverage recorded from static + // initializers. libFuzzer cleared the coverage map after they ran and could + // fail to see any coverage, triggering an early exit, if we don't replay it + // here. + // https://github.com/llvm/llvm-project/blob/957a5e987444d3193575d6ad8afe6c75da00d794/compiler-rt/lib/fuzzer/FuzzerLoop.cpp#L804-L809 + CoverageTracker::ReplayInitialCoverage(env); + } if (fuzzer_test_one_input_data_ != nullptr) { FeedFuzzedDataProvider(data, size); env.CallStaticVoidMethod(jclass_, fuzzer_test_one_input_data_, |