// 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 <elf-search.h>
#include <elf.h>
#include <lib/fdio/spawn.h>
#include <lib/fit/defer.h>
#include <lib/zx/exception.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <unistd.h>
#include <zircon/syscalls/exception.h>

#include <zxtest/zxtest.h>

#include "zircon/system/ulib/c/scudo/gwp_asan_info.h"

namespace {

constexpr const char* kHelperPath = "/pkg/bin/gwp-asan-test-use-after-free";

TEST(GwpAsanTest, HandleGwpAsanException) {
  if constexpr (!HAS_GWP_ASAN) {
    return;
  }
  // Create a job and attach an exception channel.
  zx::job test_job;
  ASSERT_OK(zx::job::create(*zx::job::default_job(), 0, &test_job));
  auto auto_call_kill_job = fit::defer([&test_job]() { test_job.kill(); });
  zx::channel exception_channel;
  ASSERT_OK(test_job.create_exception_channel(0, &exception_channel));

  // Spawn the helper process.
  const char* argv[] = {kHelperPath, nullptr};
  const char* envp[] = {
      "SCUDO_OPTIONS="
      "GWP_ASAN_Enabled=true:GWP_ASAN_SampleRate=1:GWP_ASAN_MaxSimultaneousAllocations=512",
      nullptr};
  zx::process test_process;
  char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  ASSERT_OK(fdio_spawn_etc(test_job.get(), FDIO_SPAWN_CLONE_ALL, kHelperPath, argv, envp, 0,
                           nullptr, test_process.reset_and_get_address(), err_msg),
            "%s", err_msg);

  // Wait for the helper to crash or the process to terminate.
  zx_wait_item_t wait_items[] = {
      {.handle = exception_channel.get(), .waitfor = ZX_CHANNEL_READABLE, .pending = 0},
      {.handle = test_process.get(), .waitfor = ZX_PROCESS_TERMINATED, .pending = 0},
  };
  ASSERT_OK(zx_object_wait_many(wait_items, 2, ZX_TIME_INFINITE));

  // The helper should crash and the exception channel should signal.
  ASSERT_TRUE(wait_items[0].pending & ZX_CHANNEL_READABLE);
  ASSERT_FALSE(wait_items[1].pending & ZX_PROCESS_TERMINATED);

  zx_exception_info_t info;
  zx::exception exception;
  ASSERT_OK(exception_channel.read(0, &info, exception.reset_and_get_address(), sizeof(info), 1,
                                   nullptr, nullptr));
  ASSERT_EQ(ZX_EXCP_FATAL_PAGE_FAULT, info.type);

  // The address of __libc_gwp_asan_info.
  uint64_t libc_gwp_asan_info_addr = 0;

  // Find the GWP-ASan note.
  elf_search::ForEachModule(test_process, [&](const elf_search::ModuleInfo& info) {
    if (info.name != "libc.so") {
      return;
    }
    for (const auto& phdr : info.phdrs) {
      if (phdr.p_type != PT_NOTE) {
        continue;
      }
      // Read the whole segment.
      std::vector<std::byte> notes(phdr.p_memsz);
      size_t actual;
      ASSERT_OK(
          test_process.read_memory(info.vaddr + phdr.p_vaddr, notes.data(), notes.size(), &actual));
      ASSERT_EQ(notes.size(), actual);

      uint64_t p = 0;
      while (p + sizeof(Elf64_Nhdr) <= notes.size()) {
        Elf64_Nhdr& nhdr = reinterpret_cast<Elf64_Nhdr&>(notes[p]);
        p += sizeof(Elf64_Nhdr);
        p += (nhdr.n_namesz + 3) & ~3;
        if (nhdr.n_type == GWP_ASAN_NOTE_TYPE) {
          ASSERT_EQ(sizeof(uint64_t), nhdr.n_descsz);
          ASSERT_TRUE(p + nhdr.n_descsz <= notes.size());
          libc_gwp_asan_info_addr =
              reinterpret_cast<uint64_t&>(notes[p]) + p + info.vaddr + phdr.p_vaddr;
          return;
        }
        p += (nhdr.n_descsz + 3) & ~3;
      }
    }
  });

  // Read the __libc_gwp_asan_info.
  ASSERT_NE(0, libc_gwp_asan_info_addr);
  gwp_asan::LibcGwpAsanInfo libc_gwp_asan_info;
  size_t actual;
  ASSERT_OK(test_process.read_memory(libc_gwp_asan_info_addr, &libc_gwp_asan_info,
                                     sizeof(libc_gwp_asan_info), &actual));
  ASSERT_EQ(actual, sizeof(libc_gwp_asan_info));

  // Read the allocator state and the allocator metadata.
  gwp_asan::AllocatorState state;
  ASSERT_OK(test_process.read_memory(reinterpret_cast<uintptr_t>(libc_gwp_asan_info.state), &state,
                                     sizeof(state), &actual));
  ASSERT_EQ(actual, sizeof(state));
  std::vector<gwp_asan::AllocationMetadata> metadata_list(state.MaxSimultaneousAllocations);
  ASSERT_OK(test_process.read_memory(
      reinterpret_cast<uintptr_t>(libc_gwp_asan_info.metadata), metadata_list.data(),
      sizeof(gwp_asan::AllocationMetadata) * metadata_list.size(), &actual));
  ASSERT_EQ(actual, sizeof(gwp_asan::AllocationMetadata) * metadata_list.size());

  // Magic and version should match.
  ASSERT_EQ(0, memcmp(gwp_asan::AllocatorVersionMagic::kAllocatorVersionMagic,
                      state.VersionMagic.Magic, 4));
  ASSERT_EQ(gwp_asan::AllocatorVersionMagic::kAllocatorVersion, state.VersionMagic.Version);

  // Since it's a use-after-free, ErrorPtr must be provided for the correct detection.
  ASSERT_FALSE(__gwp_asan_error_is_mine(&state, 0));
  // And it's not an internal error.
  ASSERT_EQ(0, __gwp_asan_get_internal_crash_address(&state,
                                                     state.internallyDetectedErrorFaultAddress()));

  // Read the faulting address.
  zx::thread thread;
  ASSERT_OK(exception.get_thread(&thread));
  zx_exception_report_t exception_report;
  ASSERT_OK(thread.get_info(ZX_INFO_THREAD_EXCEPTION_REPORT, &exception_report,
                            sizeof(exception_report), nullptr, nullptr));
#if defined(__x86_64__)
  uint64_t faulting_addr = exception_report.context.arch.u.x86_64.cr2;
#elif defined(__aarch64__)
  uint64_t faulting_addr = exception_report.context.arch.u.arm_64.far;
#elif defined(__riscv)
  uint64_t faulting_addr = exception_report.context.arch.u.riscv_64.tval;
#else
#error "what machine?"
#endif

  // Now we should be able to obtain the full report of the crash.
  ASSERT_TRUE(__gwp_asan_error_is_mine(&state, faulting_addr));
  ASSERT_EQ(gwp_asan::Error::USE_AFTER_FREE,
            __gwp_asan_diagnose_error(&state, metadata_list.data(), faulting_addr));
  const gwp_asan::AllocationMetadata* metadata =
      __gwp_asan_get_metadata(&state, metadata_list.data(), faulting_addr);
  ASSERT_NE(nullptr, metadata);
  ASSERT_TRUE(__gwp_asan_is_deallocated(metadata));

  // Allocation and free backtraces should contain at least 3 frames.
  uintptr_t backtrace[16];
  ASSERT_GE(__gwp_asan_get_allocation_trace(metadata, backtrace, 16), 3);
  ASSERT_GE(__gwp_asan_get_deallocation_trace(metadata, backtrace, 16), 3);
}

}  // namespace
