// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/process/process_memory_mac.h"

#include <mach/mach.h>
#include <string.h>

#include <algorithm>
#include <memory>
#include <string>

#include "base/apple/scoped_mach_port.h"
#include "base/apple/scoped_mach_vm.h"
#include "base/containers/heap_array.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.h"
#include "util/misc/from_pointer_cast.h"

namespace crashpad {
namespace test {
namespace {

TEST(ProcessMemoryMac, ReadMappedSelf) {
  vm_address_t address = 0;
  const vm_size_t kSize = 4 * PAGE_SIZE;
  kern_return_t kr =
      vm_allocate(mach_task_self(), &address, kSize, VM_FLAGS_ANYWHERE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_allocate");
  base::apple::ScopedMachVM vm_owner(address, mach_vm_round_page(kSize));

  char* region = reinterpret_cast<char*>(address);
  for (size_t index = 0; index < kSize; ++index) {
    region[index] = (index % 256) ^ ((index >> 8) % 256);
  }

  ProcessMemoryMac memory;
  ASSERT_TRUE(memory.Initialize(mach_task_self()));

  std::string result(kSize, '\0');
  std::unique_ptr<ProcessMemoryMac::MappedMemory> mapped;

  // Ensure that the entire region can be read.
  ASSERT_TRUE((mapped = memory.ReadMapped(address, kSize)));
  EXPECT_EQ(memcmp(region, mapped->data(), kSize), 0);

  // Ensure that a read of length 0 succeeds and doesn't touch the result.
  result.assign(kSize, '\0');
  std::string zeroes = result;
  ASSERT_TRUE((mapped = memory.ReadMapped(address, 0)));
  EXPECT_EQ(result, zeroes);

  // Ensure that a read starting at an unaligned address works.
  ASSERT_TRUE((mapped = memory.ReadMapped(address + 1, kSize - 1)));
  EXPECT_EQ(memcmp(region + 1, mapped->data(), kSize - 1), 0);

  // Ensure that a read ending at an unaligned address works.
  ASSERT_TRUE((mapped = memory.ReadMapped(address, kSize - 1)));
  EXPECT_EQ(memcmp(region, mapped->data(), kSize - 1), 0);

  // Ensure that a read starting and ending at unaligned addresses works.
  ASSERT_TRUE((mapped = memory.ReadMapped(address + 1, kSize - 2)));
  EXPECT_EQ(memcmp(region + 1, mapped->data(), kSize - 2), 0);

  // Ensure that a read of exactly one page works.
  ASSERT_TRUE((mapped = memory.ReadMapped(address + PAGE_SIZE, PAGE_SIZE)));
  EXPECT_EQ(memcmp(region + PAGE_SIZE, mapped->data(), PAGE_SIZE), 0);

  // Ensure that a read of a single byte works.
  ASSERT_TRUE((mapped = memory.ReadMapped(address + 2, 1)));
  EXPECT_EQ(reinterpret_cast<const char*>(mapped->data())[0], region[2]);

  // Ensure that a read of length zero works and doesn't touch the data.
  result[0] = 'M';
  ASSERT_TRUE((mapped = memory.ReadMapped(address + 3, 0)));
  EXPECT_EQ(result[0], 'M');
}

TEST(ProcessMemoryMac, ReadSelfUnmapped) {
  vm_address_t address = 0;
  const vm_size_t kSize = 2 * PAGE_SIZE;
  kern_return_t kr =
      vm_allocate(mach_task_self(), &address, kSize, VM_FLAGS_ANYWHERE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_allocate");
  base::apple::ScopedMachVM vm_owner(address, mach_vm_round_page(kSize));

  char* region = reinterpret_cast<char*>(address);
  for (size_t index = 0; index < kSize; ++index) {
    // Don't include any NUL bytes, because ReadCString stops when it encounters
    // a NUL.
    region[index] = (index % 255) + 1;
  }

  kr = vm_protect(
      mach_task_self(), address + PAGE_SIZE, PAGE_SIZE, FALSE, VM_PROT_NONE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_protect");

  ProcessMemoryMac memory;
  ASSERT_TRUE(memory.Initialize(mach_task_self()));
  std::string result(kSize, '\0');

  EXPECT_FALSE(memory.Read(address, kSize, &result[0]));
  EXPECT_FALSE(memory.Read(address + 1, kSize - 1, &result[0]));
  EXPECT_FALSE(memory.Read(address + PAGE_SIZE, 1, &result[0]));
  EXPECT_FALSE(memory.Read(address + PAGE_SIZE - 1, 2, &result[0]));
  EXPECT_TRUE(memory.Read(address, PAGE_SIZE, &result[0]));
  EXPECT_TRUE(memory.Read(address + PAGE_SIZE - 1, 1, &result[0]));

  // Do the same thing with the ReadMapped() interface.
  std::unique_ptr<ProcessMemoryMac::MappedMemory> mapped;
  EXPECT_FALSE((mapped = memory.ReadMapped(address, kSize)));
  EXPECT_FALSE((mapped = memory.ReadMapped(address + 1, kSize - 1)));
  EXPECT_FALSE((mapped = memory.ReadMapped(address + PAGE_SIZE, 1)));
  EXPECT_FALSE((mapped = memory.ReadMapped(address + PAGE_SIZE - 1, 2)));
  EXPECT_TRUE((mapped = memory.ReadMapped(address, PAGE_SIZE)));
  EXPECT_TRUE((mapped = memory.ReadMapped(address + PAGE_SIZE - 1, 1)));

  // Repeat the test with an unmapped page instead of an unreadable one. This
  // portion of the test may be flaky in the presence of other threads, if
  // another thread maps something in the region that is deallocated here.
  kr = vm_deallocate(mach_task_self(), address + PAGE_SIZE, PAGE_SIZE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_deallocate");
  vm_owner.reset(address, PAGE_SIZE);

  EXPECT_FALSE(memory.Read(address, kSize, &result[0]));
  EXPECT_FALSE(memory.Read(address + 1, kSize - 1, &result[0]));
  EXPECT_FALSE(memory.Read(address + PAGE_SIZE, 1, &result[0]));
  EXPECT_FALSE(memory.Read(address + PAGE_SIZE - 1, 2, &result[0]));
  EXPECT_TRUE(memory.Read(address, PAGE_SIZE, &result[0]));
  EXPECT_TRUE(memory.Read(address + PAGE_SIZE - 1, 1, &result[0]));

  // Do the same thing with the ReadMapped() interface.
  EXPECT_FALSE((mapped = memory.ReadMapped(address, kSize)));
  EXPECT_FALSE((mapped = memory.ReadMapped(address + 1, kSize - 1)));
  EXPECT_FALSE((mapped = memory.ReadMapped(address + PAGE_SIZE, 1)));
  EXPECT_FALSE((mapped = memory.ReadMapped(address + PAGE_SIZE - 1, 2)));
  EXPECT_TRUE((mapped = memory.ReadMapped(address, PAGE_SIZE)));
  EXPECT_TRUE((mapped = memory.ReadMapped(address + PAGE_SIZE - 1, 1)));
}

TEST(ProcessMemoryMac, ReadCStringSelfUnmapped) {
  vm_address_t address = 0;
  const vm_size_t kSize = 2 * PAGE_SIZE;
  kern_return_t kr =
      vm_allocate(mach_task_self(), &address, kSize, VM_FLAGS_ANYWHERE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_allocate");
  base::apple::ScopedMachVM vm_owner(address, mach_vm_round_page(kSize));

  char* region = reinterpret_cast<char*>(address);
  for (size_t index = 0; index < kSize; ++index) {
    // Don't include any NUL bytes, because ReadCString stops when it encounters
    // a NUL.
    region[index] = (index % 255) + 1;
  }

  kr = vm_protect(
      mach_task_self(), address + PAGE_SIZE, PAGE_SIZE, FALSE, VM_PROT_NONE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_protect");

  ProcessMemoryMac memory;
  ASSERT_TRUE(memory.Initialize(mach_task_self()));
  std::string result;
  EXPECT_FALSE(memory.ReadCString(address, &result));

  // Make sure that if the string is NUL-terminated within the mapped memory
  // region, it can be read properly.
  char terminator_or_not = '\0';
  std::swap(region[PAGE_SIZE - 1], terminator_or_not);
  ASSERT_TRUE(memory.ReadCString(address, &result));
  EXPECT_FALSE(result.empty());
  EXPECT_EQ(result.size(), PAGE_SIZE - 1u);
  EXPECT_EQ(result, region);

  // Repeat the test with an unmapped page instead of an unreadable one. This
  // portion of the test may be flaky in the presence of other threads, if
  // another thread maps something in the region that is deallocated here.
  std::swap(region[PAGE_SIZE - 1], terminator_or_not);
  kr = vm_deallocate(mach_task_self(), address + PAGE_SIZE, PAGE_SIZE);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "vm_deallocate");
  vm_owner.reset(address, PAGE_SIZE);

  EXPECT_FALSE(memory.ReadCString(address, &result));

  // Clear the result before testing that the string can be read. This makes
  // sure that the result is actually filled in, because it already contains the
  // expected value from the tests above.
  result.clear();
  std::swap(region[PAGE_SIZE - 1], terminator_or_not);
  ASSERT_TRUE(memory.ReadCString(address, &result));
  EXPECT_FALSE(result.empty());
  EXPECT_EQ(result.size(), PAGE_SIZE - 1u);
  EXPECT_EQ(result, region);
}

bool IsAddressMapped(vm_address_t address) {
  vm_address_t region_address = address;
  vm_size_t region_size;
  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
  vm_region_basic_info_64 info;
  mach_port_t object;
  kern_return_t kr = vm_region_64(mach_task_self(),
                                  &region_address,
                                  &region_size,
                                  VM_REGION_BASIC_INFO_64,
                                  reinterpret_cast<vm_region_info_t>(&info),
                                  &count,
                                  &object);
  if (kr == KERN_SUCCESS) {
    // |object| will be MACH_PORT_NULL (10.9.4 xnu-2422.110.17/osfmk/vm/vm_map.c
    // vm_map_region()), but the interface acts as if it might carry a send
    // right, so treat it as documented.
    base::apple::ScopedMachSendRight object_owner(object);

    return address >= region_address && address <= region_address + region_size;
  }

  if (kr == KERN_INVALID_ADDRESS) {
    return false;
  }

  ADD_FAILURE() << MachErrorMessage(kr, "vm_region_64");
  return false;
}

TEST(ProcessMemoryMac, MappedMemoryDeallocates) {
  // This tests that once a ProcessMemoryMac::MappedMemory object is destroyed,
  // it releases the mapped memory that it owned. Technically, this test is not
  // valid because after the mapping is released, something else (on another
  // thread) might wind up mapped in the same address. In the test environment,
  // hopefully there are either no other threads or they're all quiescent, so
  // nothing else should wind up mapped in the address.

  ProcessMemoryMac memory;
  ASSERT_TRUE(memory.Initialize(mach_task_self()));
  std::unique_ptr<ProcessMemoryMac::MappedMemory> mapped;

  static constexpr char kTestBuffer[] = "hello!";
  mach_vm_address_t test_address =
      FromPointerCast<mach_vm_address_t>(&kTestBuffer);
  ASSERT_TRUE((mapped = memory.ReadMapped(test_address, sizeof(kTestBuffer))));
  EXPECT_EQ(memcmp(kTestBuffer, mapped->data(), sizeof(kTestBuffer)), 0);

  vm_address_t mapped_address = reinterpret_cast<vm_address_t>(mapped->data());
  EXPECT_TRUE(IsAddressMapped(mapped_address));

  mapped.reset();
  EXPECT_FALSE(IsAddressMapped(mapped_address));

  // This is the same but with a big buffer that’s definitely larger than a
  // single page. This makes sure that the whole mapped region winds up being
  // deallocated.
  auto big_buffer = base::HeapArray<char>::Uninit(4 * PAGE_SIZE);
  test_address = FromPointerCast<mach_vm_address_t>(&big_buffer[0]);
  ASSERT_TRUE((mapped = memory.ReadMapped(test_address, big_buffer.size())));

  mapped_address = reinterpret_cast<vm_address_t>(mapped->data());
  vm_address_t mapped_last_address = mapped_address + big_buffer.size() - 1;
  EXPECT_TRUE(IsAddressMapped(mapped_address));
  EXPECT_TRUE(IsAddressMapped(mapped_address + PAGE_SIZE));
  EXPECT_TRUE(IsAddressMapped(mapped_last_address));

  mapped.reset();
  EXPECT_FALSE(IsAddressMapped(mapped_address));
  EXPECT_FALSE(IsAddressMapped(mapped_address + PAGE_SIZE));
  EXPECT_FALSE(IsAddressMapped(mapped_last_address));
}

TEST(ProcessMemoryMac, MappedMemoryReadCString) {
  // This tests the behavior of ProcessMemoryMac::MappedMemory::ReadCString().
  ProcessMemoryMac memory;
  ASSERT_TRUE(memory.Initialize(mach_task_self()));
  std::unique_ptr<ProcessMemoryMac::MappedMemory> mapped;

  static constexpr char kTestBuffer[] = "0\0" "2\0" "45\0" "789";
  const mach_vm_address_t kTestAddress =
      FromPointerCast<mach_vm_address_t>(&kTestBuffer);
  ASSERT_TRUE((mapped = memory.ReadMapped(kTestAddress, 10)));

  std::string string;
  ASSERT_TRUE(mapped->ReadCString(0, &string));
  EXPECT_EQ(string, "0");
  ASSERT_TRUE(mapped->ReadCString(1, &string));
  EXPECT_EQ(string, "");
  ASSERT_TRUE(mapped->ReadCString(2, &string));
  EXPECT_EQ(string, "2");
  ASSERT_TRUE(mapped->ReadCString(3, &string));
  EXPECT_EQ(string, "");
  ASSERT_TRUE(mapped->ReadCString(4, &string));
  EXPECT_EQ(string, "45");
  ASSERT_TRUE(mapped->ReadCString(5, &string));
  EXPECT_EQ(string, "5");
  ASSERT_TRUE(mapped->ReadCString(6, &string));
  EXPECT_EQ(string, "");

  // kTestBuffer’s NUL terminator was not read, so these will see an
  // unterminated string and fail.
  EXPECT_FALSE(mapped->ReadCString(7, &string));
  EXPECT_FALSE(mapped->ReadCString(8, &string));
  EXPECT_FALSE(mapped->ReadCString(9, &string));

  // This is out of the range of what was read, so it will fail.
  EXPECT_FALSE(mapped->ReadCString(10, &string));
  EXPECT_FALSE(mapped->ReadCString(11, &string));

  // Read it again, this time with a length long enough to include the NUL
  // terminator.
  ASSERT_TRUE((mapped = memory.ReadMapped(kTestAddress, 11)));

  ASSERT_TRUE(mapped->ReadCString(6, &string));
  EXPECT_EQ(string, "");

  // These should now succeed.
  ASSERT_TRUE(mapped->ReadCString(7, &string));
  EXPECT_EQ(string, "789");
  ASSERT_TRUE(mapped->ReadCString(8, &string));
  EXPECT_EQ(string, "89");
  ASSERT_TRUE(mapped->ReadCString(9, &string));
  EXPECT_EQ(string, "9");
  EXPECT_TRUE(mapped->ReadCString(10, &string));
  EXPECT_EQ(string, "");

  // These are still out of range.
  EXPECT_FALSE(mapped->ReadCString(11, &string));
  EXPECT_FALSE(mapped->ReadCString(12, &string));
}

}  // namespace
}  // namespace test
}  // namespace crashpad
