// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.fuzzer;

using zx;

/// Indicates the result of a long-running fuzzing workflow.
///
/// Fuzzers have several "long-running" workflows; that is, the fuzzer may
/// perform actions for an indefinite period of time. Fuzzing itself is the most
/// notable example, as the fuzzing engine may continuously generate new inputs
/// until an error is found. This workflow is represented by the `Fuzz` method
/// below. Other long-running workflows include `TryOne`, `Cleanse`, `Minimize`
/// and `Merge`.
///
/// These workflows continue executing after their associated call returns. Only
/// one workflow at a time may be executing. Callers can use `AddMonitor` to
/// monitor the status of the workflow, and `GetArtifact` to retrieve the
/// `Result` and optionally associated `Input` when it completes.
type Result = flexible enum : uint32 {
    /// The associated input did not cause any errors to be detected when tried.
    NO_ERRORS = 1;

    /// Trying the associated input triggered a memory allocation by an
    /// instrumented process that exceeded the configured limit.  Some fuzzing
    /// engines, such as libFuzzer, may not distinguish between this result and
    /// `OOM`. To differentiate,  examine the fuzzer output.
    BAD_MALLOC = 2;

    /// Trying the associated input triggered an exception in an instrumented
    /// process.
    CRASH = 3;

    /// Trying the associated input triggered an error in an instrumented
    /// process that was detected by a sanitizer runtime.
    DEATH = 4;

    /// Trying the associated input caused an instrumented process to exit
    /// unexpectedly. Some fuzzing engines such as libFuzzer may combine this
    /// result with `CRASH`. To differentiate, examine the fuzzer output.
    EXIT = 5;

    /// Trying the associated input triggered a memory leak in an instrumented
    /// process.
    LEAK = 6;

    /// Trying the associated input caused an instrumented process's memory
    /// usage to exceed the configured limit.
    OOM = 7;

    /// Trying the associated input took longer than the configured limit.
    TIMEOUT = 8;

    /// The associated input was produced by finding the shortest input that
    /// produces the same error as an original input. See `Minimize`.
    MINIMIZED = 9;

    /// The associated input was produced by replacing bytes in an original
    /// input with PII-free values while preserving the error produced. See
    /// `Cleanse`.
    CLEANSED = 10;

    /// The fuzzer corpus has been compacted to only include the shortest inputs
    /// that preserve overall coverage. This workflow does not have an
    /// associated input. See `Merge`.
    MERGED = 11;
};

/// Encapsulation of a fuzzer input transferred over a socket, e.g. between a
/// host and device via overnet.
type Input = resource struct {
    /// Socket that can be used to read the data.
    socket zx.Handle:SOCKET;

    /// The total amount of data to be transferred.
    size uint64;
};

/// Encapsulates the result of a long-running fuzzing workflow and optionally
/// the input that caused it, depending on the workflow.
//
// TODO(https://fxbug.dev/42074956): Include workflow enum.
type Artifact = resource table {
    /// Result of executing the long-running workflow.
    1: result Result;

    /// Optional fuzzer input produced by a specific long-running workflow. This
    /// may be:
    ///
    /// * A discovered input in the case of `Fuzz`
    /// * A constructed input in the cases of `Cleanse` and `Minimize`.
    /// * Omitted in the cases of `TryOne` and `Merge`.
    2: input Input;

    /// An error generated during a long-running workflow. These errors are
    /// distinct from those that result from validating workflow requests and
    /// are documented for the workflow methods below. These errors result from
    /// unexpected framework failure. For example, if libFuzzer fails due to an
    /// internal error, the engine will report it via this field.
    ///
    /// The `result` and `input` fields are invalid if this field is present and
    /// anything other than `ZX_OK`.
    3: error zx.Status;
};

/// Marker indicating the last message in a diagnostic output stream.
///
/// In addition to an `Artifact`, long-running workflows may also produce the
/// standard output, standard error, and system logs. These fuzzer output
/// streams are provided by `fuchsia.test_manager/SuiteRunner` and have no
/// guaranteed order with respect to FIDL responses. As a result, the streams
/// need to include an "in-band" signal that indicates when they are complete
/// for a particular workflow. Clients processing the fuzzer output may use this
/// marker to synchronize the streams and the FIDL response for `GetArtifact`.
///
/// The string is intentionally somewhat long to mitigate the likelihood of it
/// being emitted by the code under test.
///
const DONE_MARKER string = "DONE: A long-running `fuchsia.fuzzer.Controller` workflow is complete.";

/// Provides the management interface for fuzzing.
///
/// This protocol is implemented by the fuzzing engine. Clients for this
/// protocol are provided by `fuchsia.fuzzer/ControllerProvider.Connect`.
///
/// The channel is closed when the fuzzer is no longer needed, and on error.
/// Clients should exit and not attempt to reconnect.
closed protocol Controller {
    /// Sets various execution and error detection parameters. This may be
    /// called multiple times; only the most recently received options are used.
    /// If the `Options` parameter omits one or more fields, those parameters
    /// are unchanged in the fuzzer. Until the initial call to this method, the
    /// fuzzer should assume the default values for `Options`.
    ///
    /// + request `options` the execution and error detection parameters.
    /// * error one of the following:
    /// * error
    ///     * `ZX_ERR_BAD_STATE` if a long-running call such as `Execute`,
    ///       `Cleanse`, `Minimize`, `Fuzz`, or `Merge` is in progress.
    ///     * `ZX_ERR_NOT_SUPPORTED` if a value provided for an option is not
    ///       supported by the engine. Check the logs for additional details.
    strict Configure(struct {
        options Options;
    }) -> () error zx.Status;

    /// Gets the current values for the various execution and error detection
    /// parameters.
    ///
    /// - response `options` the execution and error detection parameters.
    strict GetOptions() -> (struct {
        options Options;
    });

    /// Writes the provided `input` to either the "seed" or "live" `corpus`.
    /// Returns an error if transferring the input fails; see `Input` for
    /// details.
    ///
    /// + request `corpus` the type of corpus to add to.
    /// + request `input` the sequence of bytes to add as a test input.
    /// * error one of the following:
    ///     * `ZX_ERR_INVALID_ARGS` if corpus type is invalid.
    ///     * A socket error if transferring the input fails.
    strict AddToCorpus(resource struct {
        corpus Corpus;
        input Input;
    }) -> () error zx.Status;

    /// Connects a `corpus_reader` for either the "seed" or "live" corpus.
    ///
    /// + request `corpus` the type of corpus to read from.
    /// + request `corpus_reader` the client used to send test inputs.
    strict ReadCorpus(resource struct {
        corpus Corpus;
        corpus_reader client_end:CorpusReader;
    }) -> ();

    /// Parses and loads an AFL-style dictionary. Invalid entries are logged and
    /// skipped.
    ///
    /// See also:
    ///
    /// * https://github.com/mirrorer/afl/blob/master/dictionaries/README.dictionaries
    ///
    /// + request `dictionary` the AFL-style dictionary
    /// * error one of the following:
    ///     * A socket error if transferring the input fails.
    ///     *`ZX_ERR_INVALID_ARGS` if parsing the dictionary fails.
    strict WriteDictionary(resource struct {
        dictionary Input;
    }) -> () error zx.Status;

    /// Returns the current dictionary as an Input, which may be empty.
    ///
    /// - response `dictionary` the current AFL-style dictionary.
    strict ReadDictionary() -> (resource struct {
        dictionary Input;
    });

    /// Installs a `Monitor` to push status. To pull status instead, use
    /// `GetStatus`.
    ///
    /// + request `monitor` the client used to send status updates.
    strict AddMonitor(resource struct {
        monitor client_end:Monitor;
    }) -> ();

    /// Runs the normal fuzzing feedback loop:
    ///
    /// 1. Selects an input from the corpus.
    /// 2. Mutates the input.
    /// 3. Uses the `TargetAdapter` to execute the input.
    /// 4. Checks feedback from the `InstrumentedProcesses`.
    /// 5. If the input produced useful feedback, adds it to the corpus.
    ///
    /// This call returns quickly, but the loop continues until one of three
    /// conditions is met:
    ///
    /// 1. The configured, non-zero number of `runs` has been reached.
    /// 2. The configured, non-zero `duration` elapses.
    /// 3. An error is detected, and returned.
    ///
    /// See `Result` for more details on long running workflows such as this
    /// one.
    ///
    /// * error `ZX_ERR_BAD_STATE` if another long-running workflow is in
    ///   progress.
    strict Fuzz() -> () error zx.Status;

    /// Executes the target code with a single `test_input`.
    ///
    /// See `Result` for more details on long running workflows such as this
    /// one.
    ///
    /// + request `input` the sequence of bytes to use with the fuzz target.
    /// * error one of the following:
    ///     * `ZX_ERR_BAD_STATE` if another long-running workflow is in
    ///       progress.
    ///     *  A socket error if transferring the input fails.
    strict TryOne(resource struct {
        test_input Input;
    }) -> () error zx.Status;

    /// Attempts to find the smallest input that produces the same error as the
    /// given `test_input`,
    /// constrained by the configured `total_time` and/or `runs` options.
    ///
    /// See `Result` for more details on long running workflows such as this
    /// one.
    ///
    /// + request `input` the sequence of bytes to minimize.
    /// * error one of the following:
    ///     * `ZX_ERR_BAD_STATE` if another long-running workflow is in
    ///       progress.
    ///     * A socket error if transferring the input fails.
    ///     * `ZX_ERR_INVALID_ARGS` if the provided `test_input` does not cause
    ///       an error.
    strict Minimize(resource struct {
        test_input Input;
    }) -> () error zx.Status;

    /// Attempts to replace bytes of the given `test_input` with "filler" bytes,
    /// e.g. \x00, \xFF, without changing the error produced.
    ///
    /// See `Result` for more details on long running workflows such as this
    /// one.
    ///
    /// To preserve backwards compatibility with libFuzzer and ClusterFuzz, an
    /// input that produces no result is *not* considered an error, and is
    /// returned as-is.
    ///
    /// + request `input` the sequence of bytes to cleanse.
    /// * error one of the following:
    ///     * `ZX_ERR_BAD_STATE` if another long-running workflow is in
    ///       progress.
    ///     * A socket error if transferring the input fails.
    strict Cleanse(resource struct {
        test_input Input;
    }) -> () error zx.Status;

    /// Attempts to shrink the corpora. Inputs from the seed corpus will be
    /// preserved. All other inputs will be sorted by amount of feedback
    /// produced and input size, and only those inputs that add new feedback not
    /// seen earlier in the sequence will be kept.
    ///
    /// See `Result` for more details on long running workflows such as this
    /// one.
    ///
    /// * error one of the following:
    ///     * `ZX_ERR_BAD_STATE` if another long-running workflow is in
    ///       progress.
    ///     * `ZX_ERR_INVALID_ARGS` if an input in the seed corpus causes an
    ///       error. Inputs in the live corpus that cause errors are skipped.
    strict Merge() -> () error zx.Status;

    /// Returns various fuzzing metrics, e.g. total coverage, speed, etc.
    ///
    /// - response `status` the current value of fuzzing metrics.
    strict GetStatus() -> (struct {
        status Status;
    });

    /// Returns the results of a long-running workflow.
    ///
    /// This method uses the
    /// ["hanging get" pattern](https://fuchsia.dev/fuchsia-src/development/api/fidl#hanging-get).
    /// Upon the first call for a given connection, it will immediately return
    /// the controller's current artifact. Upon subsequent calls, it will block
    /// until the controller's artifact changes before returning. Clients should
    /// use `GetStatus` to ensure the fuzzer is not idle before making a
    /// blocking call to `WatchArtifact`.
    ///
    /// Combined with the `Status.running` value obtained from `GetStatus`, this
    /// allows a (re-)connecting client to infer the state of the fuzzer:
    ///
    /// * If the fuzzer is idle and has an empty artifact, then it is
    ///   unchanged since the last connection, if any.
    /// * If the fuzzer is running and has an empty artifact, then it is
    ///   performing a long-running workflow started by a previous connection.
    ///   The client may call `WatchArtifact` again to wait for the workflow
    ///   to complete.
    /// * If the fuzzer is idle and has a non-empty artifact, then it has
    ///   completed a long-running workflow since the last connection.
    ///
    /// It is not an error for clients to disconnect while waiting for a
    /// response from this method. This method is intended to allow clients to
    /// resume waiting for a long-running workflow to complete after
    /// intentionally or inadvertently being disconnected for an indefinite
    /// amount of time.
    ///
    /// - response `artifact` the most recent result and/or error-causing input.
    strict WatchArtifact() -> (resource struct {
        artifact Artifact;
    });
};

/// Provides a `Controller` implementation.
///
/// This protocol is implemented by the fuzzing engine. This capability is *not*
/// routed. Instead, the engine uses the `fuchsia.fuzzer/Registry` channel
/// provided by the fuzz-test-runner to send the client end of this interface to
/// the fuzz-registry.
///
/// The fuzz-registry will close the channel upon error, or upon its own exit.
/// The fuzzer should exit and not attempt to reconnect when on channel close.
closed protocol ControllerProvider {
    /// Connects a client to the fuzzer.
    ///
    /// Within the component fuzzing framework, the fuzz-manager forwards
    /// `Controller` connection requests to the fuzz-registry, which uses
    /// clients of this interface provided by the fuzzers themselves to perform
    /// the connection.
    ///
    /// At most one client can be connected to a controller at any given time.
    /// A subsequent call to `Connect` will preempt and replace the existing
    /// connection.
    ///
    /// + request `controller` the connection from the client.
    strict Connect(resource struct {
        controller server_end:Controller;
    }) -> ();

    /// Interrupt any current workflow, closes the channel, and exits the
    /// fuzzing engine.
    strict Stop();
};
