// Copyright 2017 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.

// This file contains all the logic necessary to intercept allocations on
// macOS. "malloc zones" are an abstraction that allows the process to intercept
// all malloc-related functions.  There is no good mechanism [short of
// interposition] to determine new malloc zones are added, so there's no clean
// mechanism to intercept all malloc zones. This file contains logic to
// intercept the default and purgeable zones, which always exist. A cursory
// review of Chrome seems to imply that non-default zones are almost never used.
//
// This file also contains logic to intercept Core Foundation and Objective-C
// allocations. The implementations forward to the default malloc zone, so the
// only reason to intercept these calls is to re-label OOM crashes with slightly
// more details.

#include "base/allocator/allocator_interception_mac.h"

#include <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#include <errno.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
#import <objc/runtime.h>
#include <stddef.h>

#include <new>

#include "base/allocator/buildflags.h"
#include "base/allocator/malloc_zone_functions_mac.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/mach_logging.h"
#include "base/process/memory.h"
#include "base/scoped_clear_errno.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "third_party/apple_apsl/CFBase.h"

namespace base {
namespace allocator {

bool g_replaced_default_zone = false;

namespace {

bool g_oom_killer_enabled;

// Starting with Mac OS X 10.7, the zone allocators set up by the system are
// read-only, to prevent them from being overwritten in an attack. However,
// blindly unprotecting and reprotecting the zone allocators fails with
// GuardMalloc because GuardMalloc sets up its zone allocator using a block of
// memory in its bss. Explicit saving/restoring of the protection is required.
//
// This function takes a pointer to a malloc zone, de-protects it if necessary,
// and returns (in the out parameters) a region of memory (if any) to be
// re-protected when modifications are complete. This approach assumes that
// there is no contention for the protection of this memory.
void DeprotectMallocZone(ChromeMallocZone* default_zone,
                         mach_vm_address_t* reprotection_start,
                         mach_vm_size_t* reprotection_length,
                         vm_prot_t* reprotection_value) {
  mach_port_t unused;
  *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone);
  struct vm_region_basic_info_64 info;
  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
  kern_return_t result = mach_vm_region(
      mach_task_self(), reprotection_start, reprotection_length,
      VM_REGION_BASIC_INFO_64, reinterpret_cast<vm_region_info_t>(&info),
      &count, &unused);
  MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region";

  // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
  // balance it with a deallocate in case this ever changes. See 10.9.2
  // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region.
  mach_port_deallocate(mach_task_self(), unused);

  // Does the region fully enclose the zone pointers? Possibly unwarranted
  // simplification used: using the size of a full version 8 malloc zone rather
  // than the actual smaller size if the passed-in zone is not version 8.
  CHECK(*reprotection_start <=
        reinterpret_cast<mach_vm_address_t>(default_zone));
  mach_vm_size_t zone_offset =
      reinterpret_cast<mach_vm_size_t>(default_zone) -
      reinterpret_cast<mach_vm_size_t>(*reprotection_start);
  CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length);

  if (info.protection & VM_PROT_WRITE) {
    // No change needed; the zone is already writable.
    *reprotection_start = 0;
    *reprotection_length = 0;
    *reprotection_value = VM_PROT_NONE;
  } else {
    *reprotection_value = info.protection;
    result = mach_vm_protect(mach_task_self(), *reprotection_start,
                             *reprotection_length, false,
                             info.protection | VM_PROT_WRITE);
    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
  }
}

#if !defined(ADDRESS_SANITIZER)

MallocZoneFunctions g_old_zone;
MallocZoneFunctions g_old_purgeable_zone;

void* oom_killer_malloc(struct _malloc_zone_t* zone, size_t size) {
  void* result = g_old_zone.malloc(zone, size);
  if (!result && size)
    TerminateBecauseOutOfMemory(size);
  return result;
}

void* oom_killer_calloc(struct _malloc_zone_t* zone,
                        size_t num_items,
                        size_t size) {
  void* result = g_old_zone.calloc(zone, num_items, size);
  if (!result && num_items && size)
    TerminateBecauseOutOfMemory(num_items * size);
  return result;
}

void* oom_killer_valloc(struct _malloc_zone_t* zone, size_t size) {
  void* result = g_old_zone.valloc(zone, size);
  if (!result && size)
    TerminateBecauseOutOfMemory(size);
  return result;
}

void oom_killer_free(struct _malloc_zone_t* zone, void* ptr) {
  g_old_zone.free(zone, ptr);
}

void* oom_killer_realloc(struct _malloc_zone_t* zone, void* ptr, size_t size) {
  void* result = g_old_zone.realloc(zone, ptr, size);
  if (!result && size)
    TerminateBecauseOutOfMemory(size);
  return result;
}

void* oom_killer_memalign(struct _malloc_zone_t* zone,
                          size_t alignment,
                          size_t size) {
  void* result = g_old_zone.memalign(zone, alignment, size);
  // Only die if posix_memalign would have returned ENOMEM, since there are
  // other reasons why NULL might be returned (see
  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
  if (!result && size && alignment >= sizeof(void*) &&
      (alignment & (alignment - 1)) == 0) {
    TerminateBecauseOutOfMemory(size);
  }
  return result;
}

void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
  void* result = g_old_purgeable_zone.malloc(zone, size);
  if (!result && size)
    TerminateBecauseOutOfMemory(size);
  return result;
}

void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
                                  size_t num_items,
                                  size_t size) {
  void* result = g_old_purgeable_zone.calloc(zone, num_items, size);
  if (!result && num_items && size)
    TerminateBecauseOutOfMemory(num_items * size);
  return result;
}

void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
  void* result = g_old_purgeable_zone.valloc(zone, size);
  if (!result && size)
    TerminateBecauseOutOfMemory(size);
  return result;
}

void oom_killer_free_purgeable(struct _malloc_zone_t* zone, void* ptr) {
  g_old_purgeable_zone.free(zone, ptr);
}

void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
                                   void* ptr,
                                   size_t size) {
  void* result = g_old_purgeable_zone.realloc(zone, ptr, size);
  if (!result && size)
    TerminateBecauseOutOfMemory(size);
  return result;
}

void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
                                    size_t alignment,
                                    size_t size) {
  void* result = g_old_purgeable_zone.memalign(zone, alignment, size);
  // Only die if posix_memalign would have returned ENOMEM, since there are
  // other reasons why NULL might be returned (see
  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
  if (!result && size && alignment >= sizeof(void*) &&
      (alignment & (alignment - 1)) == 0) {
    TerminateBecauseOutOfMemory(size);
  }
  return result;
}

#endif  // !defined(ADDRESS_SANITIZER)

#if !defined(ADDRESS_SANITIZER)

// === Core Foundation CFAllocators ===

bool CanGetContextForCFAllocator() {
  return !base::mac::IsOSLaterThan10_14_DontCallThis();
}

CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
  ChromeCFAllocatorLions* our_allocator = const_cast<ChromeCFAllocatorLions*>(
      reinterpret_cast<const ChromeCFAllocatorLions*>(allocator));
  return &our_allocator->_context;
}

CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;

void* oom_killer_cfallocator_system_default(CFIndex alloc_size,
                                            CFOptionFlags hint,
                                            void* info) {
  void* result = g_old_cfallocator_system_default(alloc_size, hint, info);
  if (!result)
    TerminateBecauseOutOfMemory(alloc_size);
  return result;
}

void* oom_killer_cfallocator_malloc(CFIndex alloc_size,
                                    CFOptionFlags hint,
                                    void* info) {
  void* result = g_old_cfallocator_malloc(alloc_size, hint, info);
  if (!result)
    TerminateBecauseOutOfMemory(alloc_size);
  return result;
}

void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size,
                                         CFOptionFlags hint,
                                         void* info) {
  void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info);
  if (!result)
    TerminateBecauseOutOfMemory(alloc_size);
  return result;
}

#endif  // !defined(ADDRESS_SANITIZER)

// === Cocoa NSObject allocation ===

typedef id (*allocWithZone_t)(id, SEL, NSZone*);
allocWithZone_t g_old_allocWithZone;

id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) {
  id result = g_old_allocWithZone(self, _cmd, zone);
  if (!result)
    TerminateBecauseOutOfMemory(0);
  return result;
}

void UninterceptMallocZoneForTesting(struct _malloc_zone_t* zone) {
  ChromeMallocZone* chrome_zone = reinterpret_cast<ChromeMallocZone*>(zone);
  if (!IsMallocZoneAlreadyStored(chrome_zone))
    return;
  MallocZoneFunctions& functions = GetFunctionsForZone(zone);
  ReplaceZoneFunctions(chrome_zone, &functions);
}

}  // namespace

bool UncheckedMallocMac(size_t size, void** result) {
#if defined(ADDRESS_SANITIZER)
  *result = malloc(size);
#else
  if (g_old_zone.malloc) {
    *result = g_old_zone.malloc(malloc_default_zone(), size);
  } else {
    *result = malloc(size);
  }
#endif  // defined(ADDRESS_SANITIZER)

  return *result != NULL;
}

bool UncheckedCallocMac(size_t num_items, size_t size, void** result) {
#if defined(ADDRESS_SANITIZER)
  *result = calloc(num_items, size);
#else
  if (g_old_zone.calloc) {
    *result = g_old_zone.calloc(malloc_default_zone(), num_items, size);
  } else {
    *result = calloc(num_items, size);
  }
#endif  // defined(ADDRESS_SANITIZER)

  return *result != NULL;
}

void StoreFunctionsForDefaultZone() {
  ChromeMallocZone* default_zone = reinterpret_cast<ChromeMallocZone*>(
      malloc_default_zone());
  StoreMallocZone(default_zone);
}

void StoreFunctionsForAllZones() {
  // This ensures that the default zone is always at the front of the array,
  // which is important for performance.
  StoreFunctionsForDefaultZone();

  vm_address_t* zones;
  unsigned int count;
  kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count);
  if (kr != KERN_SUCCESS)
    return;
  for (unsigned int i = 0; i < count; ++i) {
    ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]);
    StoreMallocZone(zone);
  }
}

void ReplaceFunctionsForStoredZones(const MallocZoneFunctions* functions) {
  // The default zone does not get returned in malloc_get_all_zones().
  ChromeMallocZone* default_zone =
      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
  if (DoesMallocZoneNeedReplacing(default_zone, functions)) {
    ReplaceZoneFunctions(default_zone, functions);
  }

  vm_address_t* zones;
  unsigned int count;
  kern_return_t kr =
      malloc_get_all_zones(mach_task_self(), nullptr, &zones, &count);
  if (kr != KERN_SUCCESS)
    return;
  for (unsigned int i = 0; i < count; ++i) {
    ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]);
    if (DoesMallocZoneNeedReplacing(zone, functions)) {
      ReplaceZoneFunctions(zone, functions);
    }
  }
  g_replaced_default_zone = true;
}

void InterceptAllocationsMac() {
  if (g_oom_killer_enabled)
    return;

  g_oom_killer_enabled = true;

// === C malloc/calloc/valloc/realloc/posix_memalign ===

// This approach is not perfect, as requests for amounts of memory larger than
// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
// still fail with a NULL rather than dying (see
// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
// Unfortunately, it's the best we can do. Also note that this does not affect
// allocations from non-default zones.

#if !defined(ADDRESS_SANITIZER)
  // Don't do anything special on OOM for the malloc zones replaced by
  // AddressSanitizer, as modifying or protecting them may not work correctly.
  ChromeMallocZone* default_zone =
      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
  if (!IsMallocZoneAlreadyStored(default_zone)) {
    StoreZoneFunctions(default_zone, &g_old_zone);
    MallocZoneFunctions new_functions = {};
    new_functions.malloc = oom_killer_malloc;
    new_functions.calloc = oom_killer_calloc;
    new_functions.valloc = oom_killer_valloc;
    new_functions.free = oom_killer_free;
    new_functions.realloc = oom_killer_realloc;
    new_functions.memalign = oom_killer_memalign;

    ReplaceZoneFunctions(default_zone, &new_functions);
    g_replaced_default_zone = true;
  }

  ChromeMallocZone* purgeable_zone =
      reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
  if (purgeable_zone && !IsMallocZoneAlreadyStored(purgeable_zone)) {
    StoreZoneFunctions(purgeable_zone, &g_old_purgeable_zone);
    MallocZoneFunctions new_functions = {};
    new_functions.malloc = oom_killer_malloc_purgeable;
    new_functions.calloc = oom_killer_calloc_purgeable;
    new_functions.valloc = oom_killer_valloc_purgeable;
    new_functions.free = oom_killer_free_purgeable;
    new_functions.realloc = oom_killer_realloc_purgeable;
    new_functions.memalign = oom_killer_memalign_purgeable;
    ReplaceZoneFunctions(purgeable_zone, &new_functions);
  }
#endif

  // === C malloc_zone_batch_malloc ===

  // batch_malloc is omitted because the default malloc zone's implementation
  // only supports batch_malloc for "tiny" allocations from the free list. It
  // will fail for allocations larger than "tiny", and will only allocate as
  // many blocks as it's able to from the free list. These factors mean that it
  // can return less than the requested memory even in a non-out-of-memory
  // situation. There's no good way to detect whether a batch_malloc failure is
  // due to these other factors, or due to genuine memory or address space
  // exhaustion. The fact that it only allocates space from the "tiny" free list
  // means that it's likely that a failure will not be due to memory exhaustion.
  // Similarly, these constraints on batch_malloc mean that callers must always
  // be expecting to receive less memory than was requested, even in situations
  // where memory pressure is not a concern. Finally, the only public interface
  // to batch_malloc is malloc_zone_batch_malloc, which is specific to the
  // system's malloc implementation. It's unlikely that anyone's even heard of
  // it.

#ifndef ADDRESS_SANITIZER
  // === Core Foundation CFAllocators ===

  // This will not catch allocation done by custom allocators, but will catch
  // all allocation done by system-provided ones.

  CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
        !g_old_cfallocator_malloc_zone)
      << "Old allocators unexpectedly non-null";

  bool cf_allocator_internals_known = CanGetContextForCFAllocator();

  if (cf_allocator_internals_known) {
    CFAllocatorContext* context =
        ContextForCFAllocator(kCFAllocatorSystemDefault);
    CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
    g_old_cfallocator_system_default = context->allocate;
    CHECK(g_old_cfallocator_system_default)
        << "Failed to get kCFAllocatorSystemDefault allocation function.";
    context->allocate = oom_killer_cfallocator_system_default;

    context = ContextForCFAllocator(kCFAllocatorMalloc);
    CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
    g_old_cfallocator_malloc = context->allocate;
    CHECK(g_old_cfallocator_malloc)
        << "Failed to get kCFAllocatorMalloc allocation function.";
    context->allocate = oom_killer_cfallocator_malloc;

    context = ContextForCFAllocator(kCFAllocatorMallocZone);
    CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
    g_old_cfallocator_malloc_zone = context->allocate;
    CHECK(g_old_cfallocator_malloc_zone)
        << "Failed to get kCFAllocatorMallocZone allocation function.";
    context->allocate = oom_killer_cfallocator_malloc_zone;
  } else {
    DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory "
                     "failures via CFAllocator will not result in termination. "
                     "http://crbug.com/45650";
  }
#endif

  // === Cocoa NSObject allocation ===

  // Note that both +[NSObject new] and +[NSObject alloc] call through to
  // +[NSObject allocWithZone:].

  CHECK(!g_old_allocWithZone) << "Old allocator unexpectedly non-null";

  Class nsobject_class = [NSObject class];
  Method orig_method =
      class_getClassMethod(nsobject_class, @selector(allocWithZone:));
  g_old_allocWithZone =
      reinterpret_cast<allocWithZone_t>(method_getImplementation(orig_method));
  CHECK(g_old_allocWithZone)
      << "Failed to get allocWithZone allocation function.";
  method_setImplementation(orig_method,
                           reinterpret_cast<IMP>(oom_killer_allocWithZone));
}

void UninterceptMallocZonesForTesting() {
  UninterceptMallocZoneForTesting(malloc_default_zone());
  vm_address_t* zones;
  unsigned int count;
  kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count);
  CHECK(kr == KERN_SUCCESS);
  for (unsigned int i = 0; i < count; ++i) {
    UninterceptMallocZoneForTesting(
        reinterpret_cast<struct _malloc_zone_t*>(zones[i]));
  }

  ClearAllMallocZonesForTesting();
}

namespace {

void ShimNewMallocZonesAndReschedule(base::Time end_time,
                                     base::TimeDelta delay) {
  ShimNewMallocZones();

  if (base::Time::Now() > end_time)
    return;

  base::TimeDelta next_delay = delay * 2;
  SequencedTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&ShimNewMallocZonesAndReschedule, end_time, next_delay),
      delay);
}

}  // namespace

void PeriodicallyShimNewMallocZones() {
  base::Time end_time = base::Time::Now() + base::TimeDelta::FromMinutes(1);
  base::TimeDelta initial_delay = base::TimeDelta::FromSeconds(1);
  ShimNewMallocZonesAndReschedule(end_time, initial_delay);
}

void ShimNewMallocZones() {
  StoreFunctionsForAllZones();

  // Use the functions for the default zone as a template to replace those
  // new zones.
  ChromeMallocZone* default_zone =
      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
  DCHECK(IsMallocZoneAlreadyStored(default_zone));

  MallocZoneFunctions new_functions;
  StoreZoneFunctions(default_zone, &new_functions);
  ReplaceFunctionsForStoredZones(&new_functions);
}

void ReplaceZoneFunctions(ChromeMallocZone* zone,
                          const MallocZoneFunctions* functions) {
  // Remove protection.
  mach_vm_address_t reprotection_start = 0;
  mach_vm_size_t reprotection_length = 0;
  vm_prot_t reprotection_value = VM_PROT_NONE;
  DeprotectMallocZone(zone, &reprotection_start, &reprotection_length,
                      &reprotection_value);

  CHECK(functions->malloc && functions->calloc && functions->valloc &&
        functions->free && functions->realloc);
  zone->malloc = functions->malloc;
  zone->calloc = functions->calloc;
  zone->valloc = functions->valloc;
  zone->free = functions->free;
  zone->realloc = functions->realloc;
  if (functions->batch_malloc)
    zone->batch_malloc = functions->batch_malloc;
  if (functions->batch_free)
    zone->batch_free = functions->batch_free;
  if (functions->size)
    zone->size = functions->size;
  if (zone->version >= 5 && functions->memalign) {
    zone->memalign = functions->memalign;
  }
  if (zone->version >= 6 && functions->free_definite_size) {
    zone->free_definite_size = functions->free_definite_size;
  }

  // Restore protection if it was active.
  if (reprotection_start) {
    kern_return_t result =
        mach_vm_protect(mach_task_self(), reprotection_start,
                        reprotection_length, false, reprotection_value);
    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
  }
}

}  // namespace allocator
}  // namespace base
