// 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.

#include "src/sys/fuzzing/libfuzzer/testing/fuzzer.h"

#include <lib/syslog/cpp/macros.h>
#include <lib/zx/time.h>
#include <zircon/process.h>
#include <zircon/status.h>

#include <random>

#include <test/fuzzer/cpp/fidl.h>

#include "src/sys/fuzzing/common/options.h"
#include "src/sys/fuzzing/common/result.h"
#include "src/sys/fuzzing/common/testing/sanitizer.h"
#include "src/sys/fuzzing/libfuzzer/testing/feedback.h"

namespace fuzzing {

using ::test::fuzzer::Relay;
using ::test::fuzzer::RelayPtr;
using ::test::fuzzer::SignaledBuffer;

TestFuzzer::TestFuzzer() {
  context_ = ComponentContext::Create();
  eventpair_ = std::make_unique<AsyncEventPair>(context_->executor());
}

int TestFuzzer::TestOneInput(const uint8_t *data, size_t size) {
  zx_status_t retval = ZX_ERR_SHOULD_WAIT;
  auto task =
      fpromise::make_promise([this, relay = RelayPtr(), connect = ZxFuture<SignaledBuffer>()](
                                 Context &context) mutable -> ZxResult<> {
        // First, connect to the unit test via the relay, if necessary.
        if (eventpair_->IsConnected() && !relay) {
          return fpromise::ok();
        }
        if (!connect) {
          auto handler = context_->MakeRequestHandler<Relay>();
          auto executor = context_->executor();
          handler(relay.NewRequest(executor->dispatcher()));
          Bridge<SignaledBuffer> bridge;
          relay->WatchTestData(bridge.completer.bind());
          connect = ConsumeBridge(bridge);
        }
        if (!connect(context)) {
          return fpromise::pending();
        }
        if (connect.is_error()) {
          return fpromise::error(connect.error());
        }
        auto signaled_buffer = connect.take_value();
        if (auto status = test_input_buffer_.Link(std::move(signaled_buffer.test_input));
            status != ZX_OK) {
          return fpromise::error(status);
        }
        if (auto status = feedback_buffer_.Link(std::move(signaled_buffer.feedback));
            status != ZX_OK) {
          return fpromise::error(status);
        }
        eventpair_->Pair(std::move(signaled_buffer.eventpair));
        relay->Finish();
        return fpromise::ok();
      })
          .and_then([this, data, size] {
            if (auto status = test_input_buffer_.Write(data, size); status != ZX_OK) {
              return AsZxResult(status);
            }
            // Notify the unit test that the test input is ready, and wait for its
            // notification that feedback is ready.
            return AsZxResult(eventpair_->SignalPeer(0, kStart));
          })
          .and_then(eventpair_->WaitFor(kStart))
          .and_then([this](const zx_signals_t &observed) {
            return AsZxResult(eventpair_->SignalSelf(observed, 0));
          })
          .and_then([this]() -> ZxResult<> {
            const auto *feedback =
                reinterpret_cast<const RelayedFeedback *>(feedback_buffer_.data());
            for (size_t i = 0; i < feedback->num_counters; ++i) {
              const auto *counter = &feedback->counters[i];
              SetCoverage(counter->offset, counter->value);
            }
            if (feedback->leak_suspected) {
              // Without a call to the |free_hook|, the fake sanitizer should suspect a
              // leak.
              Malloc(sizeof(*this));
            }
            switch (feedback->result) {
              case FuzzResult::NO_ERRORS:
                // Notify the unit test that the fuzzer completed the run.
                return AsZxResult(eventpair_->SignalPeer(0, kFinish));
              case FuzzResult::BAD_MALLOC:
                printf("DEDUP_TOKEN: BAD_MALLOC\n");
                Malloc(size_t(-1));
                break;
              case FuzzResult::CRASH:
                printf("DEDUP_TOKEN: CRASH\n");
                Crash();
                break;
              case FuzzResult::DEATH:
                printf("DEDUP_TOKEN: DEATH\n");
                Die();
                break;
              case FuzzResult::EXIT:
                // Don't call exit() here; the atexit handlers will invoke the executors
                // destructors, which will panic since we're mid-task. Signal via error.
                printf("DEDUP_TOKEN: EXIT\n");
                return fpromise::error(ZX_ERR_STOP);
              case FuzzResult::LEAK:
                LeakMemory();
                return fpromise::ok();
              case FuzzResult::OOM:
                printf("DEDUP_TOKEN: OOM\n");
                OOM();
                break;
              case FuzzResult::TIMEOUT:
                printf("DEDUP_TOKEN: TIMEOUT\n");
                Timeout();
                break;
            }
            FX_NOTREACHED();
            return fpromise::error(ZX_ERR_INTERNAL);
          })
          .then([&retval](const ZxResult<> &result) {
            retval = result.is_ok() ? ZX_OK : result.error();
            return fpromise::ok();
          });
  // Compare with async-test.h. Unlike a real fuzzer, this fake fuzzer runs its async loop on the
  // current thread. To make |LLVMFuzzerTestOneInput| synchronous, this method needs to periodically
  // kick the loop until the promise above completes.
  context_->ScheduleTask(std::move(task));
  while (true) {
    if (auto status = context_->RunUntilIdle(); status != ZX_OK) {
      FX_LOGS(WARNING) << "Loop stopped unexpectedly: " << zx_status_get_string(status);
      return status;
    }
    // See the comment on the |FuzzResult::EXIT| case above. It is safe to call exit() here.
    if (retval == ZX_ERR_STOP) {
      exit(0);
    }
    if (retval != ZX_ERR_SHOULD_WAIT) {
      return retval;
    }
    zx::nanosleep(zx::deadline_after(zx::msec(10)));
  }
}

void TestFuzzer::Crash() { __builtin_trap(); }

void TestFuzzer::OOM() {
  // Grow at a rate of ~100 Mb/s. Even with a low RSS limit, it may take a couple seconds to OOM,
  // as libFuzzer's RSS thread runs once per second.
  std::minstd_rand prng;
  std::vector<std::vector<uint8_t>> blocks;
  const size_t block_size = 1ULL << 20;
  while (true) {
    std::vector<uint8_t> block(block_size, static_cast<uint8_t>(prng()));
    blocks.push_back(std::move(block));
    zx::nanosleep(zx::deadline_after(zx::msec(10)));
  }
}

void TestFuzzer::Timeout() {
  // Make sure libFuzzer's -timeout flag is set to something reasonable before calling this!
  zx::nanosleep(zx::time::infinite());
}

}  // namespace fuzzing

// Forward the fuzz target function required by libFuzzer to the |gFuzzer| object.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  static fuzzing::TestFuzzer fuzzer;
  return fuzzer.TestOneInput(data, size);
}
