// Copyright 2018 The Chromium 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 "base/memory/platform_shared_memory_region.h"

#include <mach/mach_vm.h>

#include "base/mac/mach_logging.h"
#include "base/mac/scoped_mach_vm.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "starboard/types.h"

#if defined(OS_IOS)
#error "MacOS only - iOS uses platform_shared_memory_region_posix.cc"
#endif

namespace base {
namespace subtle {

namespace {

void LogCreateError(PlatformSharedMemoryRegion::CreateError error,
                    kern_return_t mac_error) {
  UMA_HISTOGRAM_ENUMERATION("SharedMemory.CreateError", error);
  if (mac_error != KERN_SUCCESS)
    UmaHistogramSparse("SharedMemory.CreateMacError", mac_error);
}

}  // namespace

// static
PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Take(
    mac::ScopedMachSendRight handle,
    Mode mode,
    size_t size,
    const UnguessableToken& guid) {
  if (!handle.is_valid())
    return {};

  if (size == 0)
    return {};

  if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
    return {};

  CHECK(
      CheckPlatformHandlePermissionsCorrespondToMode(handle.get(), mode, size));

  return PlatformSharedMemoryRegion(std::move(handle), mode, size, guid);
}

// static
PlatformSharedMemoryRegion
PlatformSharedMemoryRegion::TakeFromSharedMemoryHandle(
    const SharedMemoryHandle& handle,
    Mode mode) {
  CHECK(mode == Mode::kReadOnly || mode == Mode::kUnsafe);
  CHECK(handle.GetType() == SharedMemoryHandle::MACH);
  if (!handle.IsValid())
    return {};

  return Take(base::mac::ScopedMachSendRight(handle.GetMemoryObject()), mode,
              handle.GetSize(), handle.GetGUID());
}

mach_port_t PlatformSharedMemoryRegion::GetPlatformHandle() const {
  return handle_.get();
}

bool PlatformSharedMemoryRegion::IsValid() const {
  return handle_.is_valid();
}

PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Duplicate() const {
  if (!IsValid())
    return {};

  CHECK_NE(mode_, Mode::kWritable)
      << "Duplicating a writable shared memory region is prohibited";

  // Increment the ref count.
  kern_return_t kr = mach_port_mod_refs(mach_task_self(), handle_.get(),
                                        MACH_PORT_RIGHT_SEND, 1);
  if (kr != KERN_SUCCESS) {
    MACH_DLOG(ERROR, kr) << "mach_port_mod_refs";
    return {};
  }

  return PlatformSharedMemoryRegion(mac::ScopedMachSendRight(handle_.get()),
                                    mode_, size_, guid_);
}

bool PlatformSharedMemoryRegion::ConvertToReadOnly() {
  return ConvertToReadOnly(nullptr);
}

bool PlatformSharedMemoryRegion::ConvertToReadOnly(void* mapped_addr) {
  if (!IsValid())
    return false;

  CHECK_EQ(mode_, Mode::kWritable)
      << "Only writable shared memory region can be converted to read-only";

  mac::ScopedMachSendRight handle_copy(handle_.release());

  void* temp_addr = mapped_addr;
  mac::ScopedMachVM scoped_memory;
  if (!temp_addr) {
    // Intentionally lower current prot and max prot to |VM_PROT_READ|.
    kern_return_t kr = mach_vm_map(
        mach_task_self(), reinterpret_cast<mach_vm_address_t*>(&temp_addr),
        size_, 0, VM_FLAGS_ANYWHERE, handle_copy.get(), 0, FALSE, VM_PROT_READ,
        VM_PROT_READ, VM_INHERIT_NONE);
    if (kr != KERN_SUCCESS) {
      MACH_DLOG(ERROR, kr) << "mach_vm_map";
      return false;
    }
    scoped_memory.reset(reinterpret_cast<vm_address_t>(temp_addr),
                        mach_vm_round_page(size_));
  }

  // Make new memory object.
  memory_object_size_t allocation_size = size_;
  mac::ScopedMachSendRight named_right;
  kern_return_t kr = mach_make_memory_entry_64(
      mach_task_self(), &allocation_size,
      reinterpret_cast<memory_object_offset_t>(temp_addr), VM_PROT_READ,
      named_right.receive(), MACH_PORT_NULL);
  if (kr != KERN_SUCCESS) {
    MACH_DLOG(ERROR, kr) << "mach_make_memory_entry_64";
    return false;
  }
  DCHECK_GE(allocation_size, size_);

  handle_ = std::move(named_right);
  mode_ = Mode::kReadOnly;
  return true;
}

bool PlatformSharedMemoryRegion::ConvertToUnsafe() {
  if (!IsValid())
    return false;

  CHECK_EQ(mode_, Mode::kWritable)
      << "Only writable shared memory region can be converted to unsafe";

  mode_ = Mode::kUnsafe;
  return true;
}

bool PlatformSharedMemoryRegion::MapAtInternal(off_t offset,
                                               size_t size,
                                               void** memory,
                                               size_t* mapped_size) const {
  bool write_allowed = mode_ != Mode::kReadOnly;
  vm_prot_t vm_prot_write = write_allowed ? VM_PROT_WRITE : 0;
  kern_return_t kr = mach_vm_map(
      mach_task_self(),
      reinterpret_cast<mach_vm_address_t*>(memory),  // Output parameter
      size,
      0,  // Alignment mask
      VM_FLAGS_ANYWHERE, handle_.get(), offset,
      FALSE,                         // Copy
      VM_PROT_READ | vm_prot_write,  // Current protection
      VM_PROT_READ | vm_prot_write,  // Maximum protection
      VM_INHERIT_NONE);
  if (kr != KERN_SUCCESS) {
    MACH_DLOG(ERROR, kr) << "mach_vm_map";
    return false;
  }

  *mapped_size = size;
  return true;
}

// static
PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Create(Mode mode,
                                                              size_t size) {
  if (size == 0) {
    LogCreateError(CreateError::SIZE_ZERO, KERN_SUCCESS);
    return {};
  }

  if (size > static_cast<size_t>(std::numeric_limits<int>::max())) {
    LogCreateError(CreateError::SIZE_TOO_LARGE, KERN_SUCCESS);
    return {};
  }

  CHECK_NE(mode, Mode::kReadOnly) << "Creating a region in read-only mode will "
                                     "lead to this region being non-modifiable";

  mach_vm_size_t vm_size = size;
  mac::ScopedMachSendRight named_right;
  kern_return_t kr = mach_make_memory_entry_64(
      mach_task_self(), &vm_size,
      0,  // Address.
      MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE,
      named_right.receive(),
      MACH_PORT_NULL);  // Parent handle.
  if (kr != KERN_SUCCESS)
    LogCreateError(CreateError::CREATE_FILE_MAPPING_FAILURE, kr);
  // Crash as soon as shm allocation fails to debug the issue
  // https://crbug.com/872237.
  MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_make_memory_entry_64";
  DCHECK_GE(vm_size, size);

  LogCreateError(CreateError::SUCCESS, KERN_SUCCESS);
  return PlatformSharedMemoryRegion(std::move(named_right), mode, size,
                                    UnguessableToken::Create());
}

// static
bool PlatformSharedMemoryRegion::CheckPlatformHandlePermissionsCorrespondToMode(
    PlatformHandle handle,
    Mode mode,
    size_t size) {
  mach_vm_address_t temp_addr = 0;
  kern_return_t kr =
      mach_vm_map(mach_task_self(), &temp_addr, size, 0, VM_FLAGS_ANYWHERE,
                  handle, 0, FALSE, VM_PROT_READ | VM_PROT_WRITE,
                  VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_NONE);
  if (kr == KERN_SUCCESS) {
    kern_return_t kr_deallocate =
        mach_vm_deallocate(mach_task_self(), temp_addr, size);
    MACH_DLOG_IF(ERROR, kr_deallocate != KERN_SUCCESS, kr_deallocate)
        << "mach_vm_deallocate";
  } else if (kr != KERN_INVALID_RIGHT) {
    MACH_DLOG(ERROR, kr) << "mach_vm_map";
    return false;
  }

  bool is_read_only = kr == KERN_INVALID_RIGHT;
  bool expected_read_only = mode == Mode::kReadOnly;

  if (is_read_only != expected_read_only) {
    DLOG(ERROR) << "VM region has a wrong protection mask: it is"
                << (is_read_only ? " " : " not ") << "read-only but it should"
                << (expected_read_only ? " " : " not ") << "be";
    return false;
  }

  return true;
}

PlatformSharedMemoryRegion::PlatformSharedMemoryRegion(
    mac::ScopedMachSendRight handle,
    Mode mode,
    size_t size,
    const UnguessableToken& guid)
    : handle_(std::move(handle)), mode_(mode), size_(size), guid_(guid) {}

}  // namespace subtle
}  // namespace base
