// Copyright 2020 The Chromium OS 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 <cstddef>
#include <cstdint>
#include <limits>
#include <memory>
#include <string>
#include <utility>

#include <base/check.h>
#include <base/command_line.h>
#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/test/task_environment.h>
#include <base/test/test_timeouts.h>
#include <debugd/dbus-proxy-mocks.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <gmock/gmock.h>
#include <session_manager/dbus-proxy-mocks.h>

#include "crash-reporter/chrome_collector.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/test_util.h"

namespace {

using ::testing::_;
using ::testing::WithArgs;

class Environment {
 public:
  Environment() {
    // Disable logging per instructions.
    logging::SetMinLogLevel(logging::LOGGING_FATAL);

    // Needed for TestTimeouts::Initialize(). We don't have access to the real
    // command-line, and even if we did, it's not clear we would want to use it.
    const char* const kFakeCommandLine[] = {"chrome_collector_fuzzer"};
    base::CommandLine::Init(std::size(kFakeCommandLine), kFakeCommandLine);

    // Needed for SingleThreadTaskEnvironment.
    TestTimeouts::Initialize();
  }
};

class ChromeCollectorForFuzzing : public ChromeCollector {
 public:
  explicit ChromeCollectorForFuzzing(CrashSendingMode crash_sending_mode,
                                     std::string user_name,
                                     std::string user_hash,
                                     std::string dri_error_state,
                                     std::string dmesg_result)
      : ChromeCollector(crash_sending_mode),
        user_name_(std::move(user_name)),
        user_hash_(std::move(user_hash)),
        dri_error_state_(std::move(dri_error_state)),
        dmesg_result_(std::move(dmesg_result)) {}

  void SetUpDBus() override {
    // Mock out all DBus calls so (a) we don't actually call DBus and (b) we
    // don't CHECK fail when the DBus calls fail.
    auto session_manager_mock =
        std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
    test_util::SetActiveSessions(session_manager_mock.get(),
                                 {{user_name_, user_hash_}});
    session_manager_proxy_ = std::move(session_manager_mock);

    auto proxy_mock = std::make_unique<org::chromium::debugdProxyMock>();
    std::function<void(base::OnceCallback<void(const std::string&)> &&)>
        handler_dri_error_state =
            [this](base::OnceCallback<void(const std::string&)> callback) {
              task_environment_.GetMainThreadTaskRunner()->PostNonNestableTask(
                  FROM_HERE,
                  base::BindOnce(std::move(callback), dri_error_state_));
            };
    ON_CALL(*proxy_mock, GetLogAsync("i915_error_state", _, _, _))
        .WillByDefault(WithArgs<1>(handler_dri_error_state));

    std::function<void(base::OnceCallback<void(const std::string&)> &&)>
        handler_dmesg =
            [this](base::OnceCallback<void(const std::string&)> callback) {
              task_environment_.GetMainThreadTaskRunner()->PostNonNestableTask(
                  FROM_HERE,
                  base::BindOnce(std::move(callback), dmesg_result_));
            };
    ON_CALL(*proxy_mock, CallDmesgAsync(_, _, _, _))
        .WillByDefault(WithArgs<1>(handler_dmesg));

    debugd_proxy_ = std::move(proxy_mock);
  }

 private:
  // RunLoop requires a task environment.
  base::test::SingleThreadTaskEnvironment task_environment_;
  // Results from the fake RetrieveActiveSessions call
  const std::string user_name_;
  const std::string user_hash_;
  // Results for the fake GetLogAsync call
  const std::string dri_error_state_;
  // Results for the fake CallDmesgAsync call
  const std::string dmesg_result_;
};

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment env;

  // Put all files into a per-run temp directory.
  base::ScopedTempDir temp_dir;
  CHECK(temp_dir.CreateUniqueTempDir());
  base::FilePath test_dir = temp_dir.GetPath();
  paths::SetPrefixForTesting(test_dir);

  FuzzedDataProvider provider(data, size);
  // Force daemon store on or off, since fuzzers should not have
  // non-deterministic behavior.
  bool use_daemon_store = provider.ConsumeBool();

  // Exactly one of exe_name and non_exe_error_key can be set or we CHECK fail.
  std::string exe_name;
  std::string non_exe_error_key;
  if (provider.ConsumeBool()) {
    exe_name = provider.ConsumeRandomLengthString();
    if (exe_name.empty()) {
      return 0;  // Or we'll CHECK-fail. Fuzzers shouldn't exit on any input.
    }
  } else {
    non_exe_error_key = provider.ConsumeRandomLengthString();
    if (non_exe_error_key.empty()) {
      return 0;  // Or we'll CHECK-fail. Fuzzers shouldn't exit on any input.
    }
  }

  // pid and uid must be >= 0 Or we'll CHECK-fail. Fuzzers shouldn't exit on any
  // input.
  pid_t pid = provider.ConsumeIntegralInRange(
      (pid_t)0, std::numeric_limits<pid_t>::max());
  uid_t uid = provider.ConsumeIntegralInRange(
      (uid_t)0, std::numeric_limits<uid_t>::max());
  std::string user_name = provider.ConsumeRandomLengthString();
  std::string user_hash = provider.ConsumeRandomLengthString();
  // If the user_hash looks like an absolute directory path,
  // GetDaemonStoreCrashDirectories will CHECK fail when calling
  // base::FilePath::Append().
  base::FilePath user_hash_path(user_hash);
  if (user_hash_path.IsAbsolute()) {
    return 0;
  }

  // If the user_hash_path uses "..", the fuzzer can "escape" from the temp
  // directory and overwrite random files.
  if (user_hash_path.ReferencesParent()) {
    return 0;
  }

  std::string dri_error_state = provider.ConsumeRandomLengthString();
  std::string dmesg_result = provider.ConsumeRandomLengthString();

  // Despite the Memfd in the name of HandleCrashThroughMemfd, we can pass a
  // file handle to a normal file. memfd isn't supported by QEMU so better to
  // just use normal files here.
  base::FilePath test_input_path = test_dir.Append("test_input");
  std::string input = provider.ConsumeRemainingBytesAsString();
  base::WriteFile(test_input_path, input.c_str(), input.length());
  base::File test_input(test_input_path,
                        base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!test_input.IsValid()) {
    return 0;
  }

  // Empty because otherwise we CHECK-fail if this isn't a test image.
  const std::string kEmptyDumpDir;

  // kNormalCrashSendMode -- This makes it much simpler to mock out the DBus
  // calls, and we're not fuzzing the crash loop logic.
  ChromeCollectorForFuzzing collector(
      CrashCollector::kNormalCrashSendMode, std::move(user_name),
      std::move(user_hash), std::move(dri_error_state),
      std::move(dmesg_result));
  collector.Initialize(false);
  collector.force_daemon_store_for_testing(use_daemon_store);
  collector.HandleCrashThroughMemfd(test_input.TakePlatformFile(), pid, uid,
                                    exe_name, non_exe_error_key, kEmptyDumpDir);
  return 0;
}
