diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-08-27 17:29:16 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-08-28 07:56:47 +0000 |
| commit | 9881ea45723f0f7bbc5876d48c32a7cca1fecaa3 (patch) | |
| tree | c6311149a7d225c12184c04c94d9fa659933429a /executor | |
| parent | 6c853ff934ae691d82d2ddf8d401fdd07ed4ab74 (diff) | |
executor: fix corner case of misinterpreting comparison data
Reset coverage right before scheduling next syscall for execution.
See the added comment for details.
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/executor.cc | 12 |
1 files changed, 12 insertions, 0 deletions
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; |
