Feedback

The Feedback is an entity that classifies the outcome of an execution of the program under test as interesting or not. Typically, if an execution is interesting, the corresponding input used to feed the target program is added to a corpus.

Most of the time, the notion of Feedback is deeply linked to the Observer, but they are different concepts.

The Feedback, in most of the cases, processes the information reported by one or more observers to decide if the execution is interesting. The concept of "interestingness" is abstract, but typically it is related to a novelty search (i.e. interesting inputs are those that reach a previously unseen edge in the control flow graph).

As an example, given an Observer that reports all the sizes of memory allocations, a maximization Feedback can be used to maximize these sizes to sport pathological inputs in terms of memory consumption.

In terms of code, the library offers the Feedback trait. It is used to implement functors that, given the state of the observers from the last execution, tells if the execution was interesting. So to speak, it reduces the observations to a boolean result of is_interesting - or not. For this, a Feedback can store anything it wants to persist in the fuzzers's state. This might be, for instance, the cumulative map of all edges seen so far, in the case of a feedback based on edge coverage. This can be achieved by adding Metadata in init_state and accessing it later in is_interesting. Feedback can also add custom metadata to a newly created Testcase using append_metadata.

Multiple Feedbacks can be combined into a boolean expression, considering for instance an execution as interesting if it triggers new code paths or execute in less time compared to the average execution time using feedback_or.

On top, logic operators like feedback_or and feedback_and have a _fast variant (e.g. feedback_or_fast) where the second feedback will not be evaluated, if the value of the first feedback operand already answers the interestingness question so as to save precious performance.

Using feedback_and_fast in combination with ConstFeedback, certain feedbacks can be disabled dynamically.

Objectives

While feedbacks are commonly used to decide if an Input should be kept for future mutations, they serve a double-purpose, as so-called Objective Feedbacks. In this case, the interestingness of a feedback indicates if an Objective has been hit. Commonly, these objectives would be a crash or a timeout, but they can also be used to detect if specific parts of the program have been reached, for sanitization, or a differential fuzzing success. Objectives use the same trait as a normal Feedback and the implementations can be used interchangeably.

The only difference is that interesting Objectives won't be mutated further, and are counted as Solutions, a successful fuzzing campaign.