about summary refs log tree commit diff
path: root/src/afl-fuzz-state.c
diff options
context:
space:
mode:
authorDavid Melski <melski@grammatech.com>2020-06-24 13:49:23 -0400
committerDavid Melski <melski@grammatech.com>2020-06-24 17:59:04 -0400
commitd5409714435f5cc193f93c85c455a09718e57641 (patch)
treebbb1aa0c4c496f072b373a519df2ce7b4697ea09 /src/afl-fuzz-state.c
parent1d7c76d14153d0bcb03b360e9c78f1ca1317d643 (diff)
downloadafl++-d5409714435f5cc193f93c85c455a09718e57641.tar.gz
Fix saturated maps & stability cliff in recalibration
I have observed two problems:

  1. A sudden "stability cliff" where stability drops precipitously.

  2. A sudden jump to a 100% saturated "density map".

Both issues are due to attempted "recalibration" of a case at the
beginning of fuzz_one_original() or mopt_common_fuzzing().  See the
comments "CALIBRATION (only if failed earlier on)" in those functions
and the subsequent call to calibrate_case().

At those calls to calibrate_case(), afl->fsrv.trace_bits holds
trace_bits for a run of the SUT on a prior queue entry.  However,
calibrate_case() may use the trace_bits as if they apply to the
current queue entry (afl->queue_cur).

Most often this bug causes the "stability cliff".  Trace bits are
compared for runs on distinct inputs, which can be very different.
The result is a sudden drop in stability.

Sometimes it leads to the "saturated map" problem.  A saturated
density map arises if the trace bits on the previous entry were
"simplified" by simplify_trace().  Simplified traces only contain the
values 1 and 128.  They are meant to be compared against
virgin_crashes and virgin_tmouts.

However, this bug causes the (stale) simplified trace to be compared
against virgin_bits during a call to has_new_bits(), which causes
every byte in vigin_bits to be something other than 255.  The overall
map density is determined by the percentage of bytes not 255, which
will be 100%.  Worse, AFL++ will be unable to detect novel occurrences
of edge counts 1 and 128 going forward.

This patch avoids the above issues by clearing q->exec_cksum when
calibration fails.  Recalibrations are forced to start with a fresh
trace on the queue entry.

Thanks to @andreafioraldi for suggesting the current, improved patch.
Diffstat (limited to 'src/afl-fuzz-state.c')
0 files changed, 0 insertions, 0 deletions