aboutsummaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-10-19 08:54:31 +0200
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-10-19 11:07:51 +0200
commit387398baff2e3f37b2fa25a5f3c85a0c9b925e9e (patch)
tree6eebc2a2f938eeef927f46886a5000d1626f440f /driver
parentfab033324a64a4e02e638cc6c7b243fba1846f61 (diff)
downloadjazzer-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.cpp12
-rw-r--r--driver/coverage_tracker.h1
-rw-r--r--driver/fuzz_target_runner.cpp12
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_,