Class PerfFuzzGuidance

  • All Implemented Interfaces:
    Guidance

    public class PerfFuzzGuidance
    extends AFLGuidance
    A front-end that uses AFL for increasing performance counters in addition to code coverage.

    This class extends AFLGuidance to additionally provide feedback about performance measures such as branch counts or allocation sizes.

    The type of performance metric used is configured by a system property: jqf.afl.perfFeedbackType, which must have one of the values specified in the enum PerfFuzzGuidance.PerfFeedbackType. This guidance must be used in accordance with the right run scripts that configure the instrumentation to emit trace events related to events such as heap-memory loads and allocations.

    This guidance class only works with a modified version of AFL that is designed to maximize performance counters. It will not work properly with stock AFL since it attempts to send more data to AFL than it usually expects.

    Author:
    Rohan Padhye
    • Field Detail

      • PERF_MAP_SIZE

        protected static final int PERF_MAP_SIZE
        The size of the "performance" map that will be sent to AFL.
        See Also:
        Constant Field Values
      • branchCounts

        protected Counter branchCounts
        Maps branches to counts
      • totalBranchCount

        protected int totalBranchCount
        Count of total number of branches
      • allocCounts

        protected Counter allocCounts
        Maps allocation sites to counts
      • memoryAccesses

        protected MapOfCounters memoryAccesses
        Maps acyclic execution contexts to accessed memory locations.
      • callingContext

        protected PerfFuzzGuidance.CallingContext callingContext
        Maintains a dynamic calling context (i.e. call stack).

        Note: We assume there is only a single app thread running. For supporting multiple threads, we would have to store a map from threads to calling contexts.

    • Method Detail

      • getInput

        public InputStream getInput()
        Description copied from class: AFLGuidance
        Returns an input stream containing the bytes that AFL has written to.
        Specified by:
        getInput in interface Guidance
        Overrides:
        getInput in class AFLGuidance
        Returns:
        a stream of bytes to be used by the input generator(s)
      • handleEvent

        protected void handleEvent​(TraceEvent e)
        Description copied from class: AFLGuidance
        Records branch coverage by snooping on branch events and incrementing the branch-specific counter in the tracebits map.
        Overrides:
        handleEvent in class AFLGuidance
        Parameters:
        e - the trace event to handle
      • handleResult

        public void handleResult​(Result result,
                                 Throwable error)
        Description copied from class: AFLGuidance
        Notifies the AFL proxy that a run has completed and whether it was a success. 1

        This method also sends coverage information back to the AFL proxy, which is responsible for updating the shared memory region used by afl-fuzz.

        If the trial resulted in an assumption violation, we do not mark it is a crash, but we also do not send any coverage feedback so that AFL does not consider the last input interesting enough to keep in its queue.

        Specified by:
        handleResult in interface Guidance
        Overrides:
        handleResult in class AFLGuidance
        Parameters:
        result - the result of the fuzzing trial
        error - the exception thrown by the test, or null
      • hashMemorylocation

        protected int hashMemorylocation​(int objectId,
                                         String field)
      • getAyclicExecutionContextForEvent

        protected int getAyclicExecutionContextForEvent​(TraceEvent e)
      • computeRedundancyScore

        public static double computeRedundancyScore​(org.eclipse.collections.api.list.primitive.IntList accessCounts)
        Computes a "redundancy score" for memory accesses at some program location or AEC.

        The redundancy score formula is chosen such that the value is high when many memory locations are accessed many times each. For a total of N^2 accesses, the score is maximized when N items are accessed N times each. The score is zero when either all items are accessed just once or when only one item is accessed always.

        Parameters:
        accessCounts - A collection of access counts, one positive integer for each memory access
        Returns:
        the redundancy score
      • discretizeScore

        public static int discretizeScore​(double score)
        Discretizes a redundancy score to a 32-bit value.
        Parameters:
        score - a value between 0.0 and 1.0, inclusive
        Returns:
        a value between 0 and 2^31-1, inclusive