// 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/RunBuilder` 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();
};
