From 9881ea45723f0f7bbc5876d48c32a7cca1fecaa3 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 27 Aug 2024 17:29:16 +0200 Subject: executor: fix corner case of misinterpreting comparison data Reset coverage right before scheduling next syscall for execution. See the added comment for details. --- executor/executor.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'executor/executor.cc') diff --git a/executor/executor.cc b/executor/executor.cc index 3757f2698..305675bce 100644 --- a/executor/executor.cc +++ b/executor/executor.cc @@ -1095,6 +1095,18 @@ thread_t* schedule_call(int call_index, int call_num, uint64 copyout_index, uint th->copyout_pos = pos; th->copyout_index = copyout_index; event_reset(&th->done); + // We do this both right before execute_syscall in the thread and here because: + // the former is useful to reset all unrelated coverage from our syscalls (e.g. futex in event_wait), + // while the reset here is useful to avoid the following scenario that the fuzzer was able to trigger. + // If the test program contains seccomp syscall that kills the worker thread on the next syscall, + // then it won't receive this next syscall and won't do cover_reset. If we are collecting comparions + // then we've already transformed comparison data from the previous syscall into rpc::ComparisonRaw + // in write_comparisons. That data is still in the buffer. The first word of rpc::ComparisonRaw is PC + // which overlaps with comparison type in kernel exposed records. As the result write_comparisons + // that will try to write out data from unfinished syscalls will see these rpc::ComparisonRaw records, + // mis-interpret PC as type, and fail as: SYZFAIL: invalid kcov comp type (type=ffffffff8100b4e0). + if (flag_coverage) + cover_reset(&th->cov); th->executing = true; th->call_index = call_index; th->call_num = call_num; -- cgit mrf-deployment