// Copyright 2017 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 <lib/fdio/spawn.h>
#include <lib/fit/defer.h>
#include <lib/zx/channel.h>
#include <lib/zx/process.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <limits.h>
#include <pthread.h>
#include <zircon/sanitizer.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

#include <array>
#include <atomic>
#include <filesystem>

#include <fbl/algorithm.h>
#include <zxtest/zxtest.h>

#if __has_feature(address_sanitizer)
#include <sanitizer/asan_interface.h>
#endif

#include "exit-hook-test-helper.h"

namespace {

#if __has_feature(address_sanitizer)

constexpr size_t kMaxVmos = 8192;
zx_info_vmo vmos[kMaxVmos];

constexpr size_t kMaxMaps = 8192;
zx_info_maps maps[kMaxMaps];

// Returns the koid of the ASAN Shadow vmo.
zx_status_t GetAsanShadowVmoKoid(zx_koid_t* vmo_koid) {
  if (vmo_koid == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  uintptr_t shadow_offset = __sanitizer_shadow_bounds().shadow_base;

  size_t actual, available;
  zx_status_t res =
      zx::process::self()->get_info(ZX_INFO_PROCESS_MAPS, maps, sizeof(maps), &actual, &available);
  if (res != ZX_OK)
    return res;
  if (available > kMaxMaps)
    return ZX_ERR_NO_RESOURCES;

  for (size_t i = 0; i < actual; i++) {
    if (maps[i].type != ZX_INFO_MAPS_TYPE_MAPPING)
      continue;
    if (shadow_offset >= maps[i].base && shadow_offset < maps[i].base + maps[i].size) {
      *vmo_koid = maps[i].u.mapping.vmo_koid;
      return ZX_OK;
    }
  }

  return ZX_ERR_NOT_FOUND;
}

zx_status_t GetStats(zx_koid_t vmo_koid, uint64_t* committed_bytes,
                     uint64_t* committed_change_events) {
  size_t actual, available;
  zx_status_t res =
      zx::process::self()->get_info(ZX_INFO_PROCESS_VMOS, vmos, sizeof(vmos), &actual, &available);
  if (res != ZX_OK)
    return res;
  if (available > kMaxVmos)
    return ZX_ERR_NO_RESOURCES;

  for (size_t i = 0; i < actual; i++) {
    if (vmos[i].koid == vmo_koid) {
      if (committed_bytes)
        *committed_bytes = vmos[i].committed_bytes;
      if (committed_change_events)
        *committed_change_events = vmos[i].committed_change_events;
      return ZX_OK;
    }
  }
  return ZX_ERR_NOT_FOUND;
}

zx_status_t GetMemoryUsage(zx_koid_t vmo_koid, uint64_t* committed_bytes) {
  return GetStats(vmo_koid, committed_bytes, /* Committed Change Events */ nullptr);
}

zx_status_t GetCommitChangeEvents(zx_koid_t vmo_koid, uint64_t* committed_change_events) {
  return GetStats(vmo_koid, /* Memory Usage */ nullptr, committed_change_events);
}

// c++ complains if we try to do PAGE_SIZE << shadow_scale.
const size_t kPageSize = zx_system_get_page_size();

// Touch every page in the region to make sure it's been COW'd.
__attribute__((no_sanitize("all"))) static void PrefaultPages(uintptr_t start, uintptr_t end) {
  while (start < end) {
    auto ptr = reinterpret_cast<volatile uintptr_t*>(start);
    *ptr = *ptr;
    start += kPageSize;
  }
}

// Calls PrefaultPages on every page in the current thread's stack.
static void PrefaultStackPages() {
  pthread_attr_t attr;
  ASSERT_EQ(pthread_getattr_np(pthread_self(), &attr), 0);

  void* stackaddr;
  size_t stacksize;
  ASSERT_EQ(pthread_attr_getstack(&attr, &stackaddr, &stacksize), 0);

  uintptr_t stackstart = reinterpret_cast<uintptr_t>(stackaddr);
  uintptr_t stackend = reinterpret_cast<uintptr_t>(stackaddr) + stacksize;

  // Prefault all stack pages to make sure this doesn't happen later while
  // collecting samples.
  PrefaultPages(stackstart, stackend);
  // We also need to prefault all stack shadow pages.
  size_t shadow_scale;
  size_t shadow_offset;
  __asan_get_shadow_mapping(&shadow_scale, &shadow_offset);
  PrefaultPages((stackstart >> shadow_scale) + shadow_offset,
                (stackend >> shadow_scale) + shadow_offset);
}

TEST(SanitizerUtilsTest, FillShadow) {
  zx_koid_t shadow_koid;
  ASSERT_OK(GetAsanShadowVmoKoid(&shadow_koid));

  uint64_t start_events, end_events;
  uint64_t init_mem_use;
  uint64_t alloc_mem_use;
  uint64_t memset_mem_use;
  uint64_t fill_shadow_mem_use;

  const size_t len = 32 * kPageSize;

  // We are testing that the shadow decommit operation works.
  // A previous test could have left the shadow in an uncommitted state.
  // By creating an aligned vmar, and decommitting its shadow before the test
  // starts, we guarantee that all the vmos we map inside it will have a
  // decommitted shadow as well.
  zx::vmar vmar;
  uintptr_t vmar_addr;
  ASSERT_OK(zx::vmar::root_self()->allocate(
      ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_ALIGN_64KB, 0, len, &vmar, &vmar_addr));
  auto cleanup = fit::defer([&vmar]() { vmar.destroy(); });

  __sanitizer_fill_shadow(vmar_addr, len, /* value */ 0, /* threshold */ 0);

  do {
    ASSERT_OK(GetCommitChangeEvents(shadow_koid, &start_events));

    PrefaultStackPages();

    ASSERT_OK(GetMemoryUsage(shadow_koid, &init_mem_use));

    // Allocate some memory...
    zx::vmo vmo;
    ASSERT_OK(zx::vmo::create(0, 0, &vmo));
    uintptr_t addr;
    ASSERT_OK(vmar.map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, len, &addr));

    ASSERT_OK(GetMemoryUsage(shadow_koid, &alloc_mem_use));

    // ..and poison it.
    ASAN_POISON_MEMORY_REGION((void*)addr, len);

    // Snapshot the memory use after the allocation.
    ASSERT_OK(GetMemoryUsage(shadow_koid, &memset_mem_use));

    // Unpoison the shadow.
    __sanitizer_fill_shadow(addr, len, /* value */ 0, /* threshold */ 0);

    ASSERT_OK(GetMemoryUsage(shadow_koid, &fill_shadow_mem_use));
    ASSERT_OK(GetCommitChangeEvents(shadow_koid, &end_events));

    // Deallocate the memory.
    ASSERT_OK(vmar.unmap(addr, len));
    __sanitizer_fill_shadow(vmar_addr, len, /* value */ 0, /* threshold */ 0);
  } while (end_events != start_events);
  EXPECT_GE(alloc_mem_use, init_mem_use, "");
  EXPECT_GT(memset_mem_use, alloc_mem_use, "");
  EXPECT_LT(fill_shadow_mem_use, memset_mem_use, "");
}

TEST(SanitizerUtilsTest, FillShadowSmall) {
  zx_koid_t shadow_koid;
  ASSERT_OK(GetAsanShadowVmoKoid(&shadow_koid));

  size_t shadow_scale;
  __asan_get_shadow_mapping(&shadow_scale, nullptr);

  // This tests that unpoisoning less than 1 shadow page of memory works.
  // This size ends up being three shadow pages, that way we can guarantee to
  // always have an address that is aligned to a shadow page.
  const size_t len = (kPageSize << shadow_scale) * 3;

  // We are testing that the shadow decommit operation works.
  // A previous test could have left the shadow in an uncommitted state.
  // By creating an aligned vmar, and decommitting its shadow before the test
  // starts, we guarantee that all the vmos we map inside it will have a
  // decommitted shadow as well.
  zx::vmar vmar;
  uintptr_t vmar_addr;
  ASSERT_OK(zx::vmar::root_self()->allocate(
      ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_ALIGN_64KB, 0, len, &vmar, &vmar_addr));
  auto cleanup = fit::defer([&vmar]() { vmar.destroy(); });

  __sanitizer_fill_shadow(vmar_addr, len, /* value */ 0, /* threshold */ 0);

  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(0, 0, &vmo));

  std::array<size_t, 4> sizes = {kPageSize << shadow_scale, (kPageSize / 2) << shadow_scale,
                                 (kPageSize + 1) << shadow_scale, kPageSize};

  std::array<ssize_t, 3> offsets = {-(1 << shadow_scale), 0, (1 << shadow_scale)};

  for (const auto size : sizes) {
    for (const auto offset : offsets) {
      uint64_t start_events, end_events;
      uint64_t init_mem_use;
      uint64_t final_mem_use;

      do {
        ASSERT_OK(GetCommitChangeEvents(shadow_koid, &start_events));

        PrefaultStackPages();

        uintptr_t addr;
        ASSERT_OK(vmar.map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, len, &addr));
        // Align base to the next shadow page, leaving one shadow page to its left.
        uintptr_t base = (addr + (kPageSize << shadow_scale)) & -(kPageSize << shadow_scale);

        ASSERT_OK(GetMemoryUsage(shadow_koid, &init_mem_use));

        // Poison the shadow.
        ASAN_POISON_MEMORY_REGION((void*)(base + offset), size);

        // Unpoison it.
        __sanitizer_fill_shadow(base + offset, size, 0 /* val */, 0 /* threshold */);

        ASSERT_OK(GetMemoryUsage(shadow_koid, &final_mem_use));

        ASSERT_OK(GetCommitChangeEvents(shadow_koid, &end_events));

        // Deallocate the memory.
        ASSERT_OK(vmar.unmap(addr, len));
        __sanitizer_fill_shadow(vmar_addr, len, /* value */ 0, /* threshold */ 0);
      } while (start_events != end_events);

      // At most we are leaving 2 ASAN shadow pages committed.
      EXPECT_LE(init_mem_use, final_mem_use, "");
      EXPECT_LE(final_mem_use - init_mem_use, kPageSize * 2, "");
    }
  }
}

TEST(SanitizerUtilsTest, FillShadowPartialPages) {
  zx_koid_t shadow_koid;
  ASSERT_OK(GetAsanShadowVmoKoid(&shadow_koid));

  size_t shadow_scale;
  __asan_get_shadow_mapping(&shadow_scale, nullptr);
  const size_t len = (kPageSize << shadow_scale) * 7;
  const size_t shadow_granule = (1 << shadow_scale);

  // We are testing that the shadow decommit operation works.
  // A previous test could have left the shadow in an uncommitted state.
  // By creating an aligned vmar, and decommitting its shadow before the test
  // starts, we guarantee that all the vmos we map inside it will have a
  // decommitted shadow as well.
  zx::vmar vmar;
  uintptr_t vmar_addr;
  ASSERT_OK(zx::vmar::root_self()->allocate(
      ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_ALIGN_64KB, 0, len, &vmar, &vmar_addr));
  auto cleanup = fit::defer([&vmar]() { vmar.destroy(); });

  __sanitizer_fill_shadow(vmar_addr, len, /* value */ 0, /* threshold */ 0);

  std::array<size_t, 4> paddings = {1, kPageSize, 127, (kPageSize) + 16};

  for (size_t padding : paddings) {
    // __sanitizer_fill_shadow works with sizes aligned to shadow_granule.
    padding = fbl::round_up(padding, shadow_granule);
    uint64_t start_events, end_events;
    uint64_t init_mem_use;
    uint64_t final_mem_use;
    do {
      ASSERT_OK(GetCommitChangeEvents(shadow_koid, &start_events));

      PrefaultStackPages();

      // Allocate memory...
      zx::vmo vmo;
      ASSERT_OK(zx::vmo::create(0, 0, &vmo));
      uintptr_t addr;
      ASSERT_OK(vmar.map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, len, &addr));

      // Leave the first and last shadow pages unpoisoned.
      uintptr_t poison_base = addr + (kPageSize << shadow_scale);
      size_t poison_len = len - (kPageSize << shadow_scale) * 2;

      // Partially poison some of the memory.
      poison_base += padding;
      poison_len -= padding * 2;

      ASSERT_OK(GetMemoryUsage(shadow_koid, &init_mem_use));

      ASAN_POISON_MEMORY_REGION((void*)poison_base, poison_len);

      // Unpoison the shadow.
      __sanitizer_fill_shadow(poison_base, poison_len, /* value */ 0, /* threshold */ 0);

      ASSERT_OK(GetMemoryUsage(shadow_koid, &final_mem_use));

      ASSERT_OK(GetCommitChangeEvents(shadow_koid, &end_events));

      // Deallocate the memory.
      ASSERT_OK(vmar.unmap(addr, len));
      __sanitizer_fill_shadow(vmar_addr, len, /* value */ 0, /* threshold */ 0);
    } while (end_events != start_events);

    // We expect the memory use to stay the same.
    EXPECT_EQ(init_mem_use, final_mem_use, "");
  }
}

#endif

void RunExe(std::string_view path, uint32_t expected_ret) {
  const char* root_dir = getenv("TEST_ROOT_DIR");
  if (!root_dir) {
    root_dir = "/pkg";
  }
  std::filesystem::path file(root_dir);
  file /= path;
  ASSERT_TRUE(std::filesystem::exists(file), "\"%s\" from TEST_ROOT_DIR=\"%s\"", file.c_str(),
              root_dir);

  zx::process child;
  const char* argv[] = {file.c_str(), nullptr};
  ASSERT_OK(fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, argv[0], argv,
                       child.reset_and_get_address()));

  zx_signals_t signals;
  ASSERT_OK(child.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), &signals));
  ASSERT_TRUE(signals & ZX_PROCESS_TERMINATED);

  zx_info_process_t info;
  ASSERT_OK(child.get_info(ZX_INFO_PROCESS, &info, sizeof(info), nullptr, nullptr));

  EXPECT_EQ(info.return_code, expected_ret);
}

TEST(SanitizerUtilsTest, ProcessExitHook) {
  RunExe("bin/sanitizer-exit-hook-test-helper", kHookStatus);
}

TEST(SanitizerUtilsTest, ModuleLoadedStartup) {
  RunExe("bin/sanitizer-module-loaded-test-helper", 0);
}

}  // namespace
