// Copyright 2015 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/mach/exception_types.h"

#include <Availability.h>
#include <dlfcn.h>
#include <errno.h>
#include <kern/exc_resource.h>
#include <libproc.h>
#include <strings.h>

#include "base/apple/mach_logging.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "util/mac/mac_util.h"
#include "util/mach/mach_extensions.h"
#include "util/misc/no_cfi_icall.h"
#include "util/numeric/in_range_cast.h"

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_9

extern "C" {

// proc_get_wakemon_params() is present in the OS X 10.9 SDK, but no declaration
// is provided. This provides a declaration and marks it for weak import if the
// deployment target is below 10.9.
int proc_get_wakemon_params(pid_t pid, int* rate_hz, int* flags)
    __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);

// Redeclare the method without the availability annotation to suppress the
// -Wpartial-availability warning.
int proc_get_wakemon_params(pid_t pid, int* rate_hz, int* flags);

}  // extern "C"

#else

namespace {

using ProcGetWakemonParamsType = int (*)(pid_t, int*, int*);

// The SDK doesn’t have proc_get_wakemon_params() to link against, even with
// weak import. This function returns a function pointer to it if it exists at
// runtime, or nullptr if it doesn’t. proc_get_wakemon_params() is looked up in
// the same module that provides proc_pidinfo().
ProcGetWakemonParamsType GetProcGetWakemonParams() {
  Dl_info dl_info;
  if (!dladdr(reinterpret_cast<void*>(proc_pidinfo), &dl_info)) {
    return nullptr;
  }

  void* dl_handle =
      dlopen(dl_info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
  if (!dl_handle) {
    return nullptr;
  }

  ProcGetWakemonParamsType proc_get_wakemon_params =
      reinterpret_cast<ProcGetWakemonParamsType>(
          dlsym(dl_handle, "proc_get_wakemon_params"));
  return proc_get_wakemon_params;
}

}  // namespace

#endif

namespace {

// Wraps proc_get_wakemon_params(), calling it if the system provides it. It’s
// present on OS X 10.9 and later. If it’s not available, sets errno to ENOSYS
// and returns -1.
int ProcGetWakemonParams(pid_t pid, int* rate_hz, int* flags) {
#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9
  // proc_get_wakemon_params() isn’t in the SDK. Look it up dynamically.
  static crashpad::NoCfiIcall<ProcGetWakemonParamsType> proc_get_wakemon_params(
      GetProcGetWakemonParams());
#endif

#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9
  // proc_get_wakemon_params() is definitely available if the deployment target
  // is 10.9 or newer.
  if (!proc_get_wakemon_params) {
    errno = ENOSYS;
    return -1;
  }
#endif

  return proc_get_wakemon_params(pid, rate_hz, flags);
}

}  // namespace

namespace crashpad {

exception_type_t ExcCrashRecoverOriginalException(
    mach_exception_code_t code_0,
    mach_exception_code_t* original_code_0,
    int* signal) {
  // 10.9.4 xnu-2422.110.17/bsd/kern/kern_exit.c proc_prepareexit() sets code[0]
  // based on the signal value, original exception type, and low 20 bits of the
  // original code[0] before calling xnu-2422.110.17/osfmk/kern/exception.c
  // task_exception_notify() to raise an EXC_CRASH.
  //
  // The list of core-generating signals (as used in proc_prepareexit()’s call
  // to hassigprop()) is in 10.9.4 xnu-2422.110.17/bsd/sys/signalvar.h sigprop:
  // entires with SA_CORE are in the set. These signals are SIGQUIT, SIGILL,
  // SIGTRAP, SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV, and SIGSYS. Processes
  // killed for code-signing reasons will be killed by SIGKILL and are also
  // eligible for EXC_CRASH handling, but processes killed by SIGKILL for other
  // reasons are not.
  if (signal) {
    *signal = (code_0 >> 24) & 0xff;
  }

  if (original_code_0) {
    *original_code_0 = code_0 & 0xfffff;
  }

  return (code_0 >> 20) & 0xf;
}

bool ExcCrashCouldContainException(exception_type_t exception) {
  // EXC_CRASH should never be wrapped in another EXC_CRASH.
  //
  // EXC_RESOURCE and EXC_GUARD are software exceptions that are never wrapped
  // in EXC_CRASH. The only time EXC_CRASH is generated is for processes exiting
  // due to an unhandled core-generating signal or being killed by SIGKILL for
  // code-signing reasons. Neither of these apply to EXC_RESOURCE or EXC_GUARD.
  // See 10.10 xnu-2782.1.97/bsd/kern/kern_exit.c proc_prepareexit(). Receiving
  // these exception types wrapped in EXC_CRASH would lose information because
  // their code[0] uses all 64 bits (see ExceptionSnapshotMac::Initialize()) and
  // the code[0] recovered from EXC_CRASH only contains 20 significant bits.
  //
  // EXC_CORPSE_NOTIFY may be generated from EXC_CRASH, but the opposite should
  // never occur.
  //
  // kMachExceptionSimulated is a non-fatal Crashpad-specific pseudo-exception
  // that never exists as an exception within the kernel and should thus never
  // be wrapped in EXC_CRASH.
  return exception != EXC_CRASH &&
         exception != EXC_RESOURCE &&
         exception != EXC_GUARD &&
         exception != EXC_CORPSE_NOTIFY &&
         exception != kMachExceptionSimulated;
}

int32_t ExceptionCodeForMetrics(exception_type_t exception,
                                mach_exception_code_t code_0) {
  if (exception == kMachExceptionSimulated) {
    return exception;
  }

  int signal = 0;
  if (exception == EXC_CRASH) {
    const exception_type_t original_exception =
        ExcCrashRecoverOriginalException(code_0, &code_0, &signal);
    if (!ExcCrashCouldContainException(original_exception)) {
      LOG(WARNING) << "EXC_CRASH should not contain exception "
                   << original_exception;
      return InRangeCast<uint16_t>(original_exception, 0xffff) << 16;
    }
    exception = original_exception;
  }

  uint16_t metrics_exception = InRangeCast<uint16_t>(exception, 0xffff);

  uint16_t metrics_code_0;
  switch (exception) {
    case EXC_RESOURCE:
      metrics_code_0 = (EXC_RESOURCE_DECODE_RESOURCE_TYPE(code_0) << 8) |
                       EXC_RESOURCE_DECODE_FLAVOR(code_0);
      break;

    case EXC_GUARD: {
      // This will be GUARD_TYPE_MACH_PORT (1) from <mach/port.h> or
      // GUARD_TYPE_FD (2) from 10.12.2 xnu-3789.31.2/bsd/sys/guarded.h
      const uint8_t guard_type = (code_0) >> 61;

      // These exceptions come through 10.12.2
      // xnu-3789.31.2/osfmk/ipc/mach_port.c mach_port_guard_exception() or
      // xnu-3789.31.2/bsd/kern/kern_guarded.c fp_guard_exception(). In each
      // case, bits 32-60 of code_0 encode the guard type-specific “flavor”. For
      // Mach port guards, these flavor codes come from the
      // mach_port_guard_exception_codes enum in <mach/port.h>. For file
      // descriptor guards, they come from the guard_exception_codes enum in
      // xnu-3789.31.2/bsd/sys/guarded.h. Both of these enums define shifted-bit
      // values (1 << 0, 1 << 1, 1 << 2, etc.) In actual usage as determined by
      // callers to these functions, these “flavor” codes are never ORed with
      // one another. For the purposes of encoding these codes for metrics,
      // convert the flavor codes to their corresponding bit shift values.
      const uint32_t guard_flavor = (code_0 >> 32) & 0x1fffffff;
      const int first_bit = ffs(guard_flavor);
      uint8_t metrics_guard_flavor;
      if (first_bit) {
        metrics_guard_flavor = first_bit - 1;

        const uint32_t test_guard_flavor = 1 << metrics_guard_flavor;
        if (guard_flavor != test_guard_flavor) {
          // Another bit is set.
          DCHECK_EQ(guard_flavor, test_guard_flavor);
          metrics_guard_flavor = 0xff;
        }
      } else {
        metrics_guard_flavor = 0xff;
      }

      metrics_code_0 = (guard_type << 8) | metrics_guard_flavor;
      break;
    }

    case EXC_CORPSE_NOTIFY:
      // code_0 may be a pointer. See 10.12.2 xnu-3789.31.2/osfmk/kern/task.c
      // task_deliver_crash_notification(). Just encode 0 for metrics purposes.
      metrics_code_0 = 0;
      break;

    default:
      metrics_code_0 = InRangeCast<uint16_t>(code_0, 0xffff);
      if (exception == 0 && metrics_code_0 == 0 && signal != 0) {
        // This exception came from a signal that did not originate as another
        // Mach exception. Encode the signal number, using EXC_CRASH as the
        // top-level exception type. This is safe because EXC_CRASH will not
        // otherwise appear as metrics_exception.
        metrics_exception = EXC_CRASH;
        metrics_code_0 = signal;
      }
      break;
  }

  return (metrics_exception << 16) | metrics_code_0;
}

bool IsExceptionNonfatalResource(exception_type_t exception,
                                 mach_exception_code_t code_0,
                                 pid_t pid) {
  if (exception != EXC_RESOURCE) {
    return false;
  }

  const int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(code_0);
  const int resource_flavor = EXC_RESOURCE_DECODE_FLAVOR(code_0);

  if (resource_type == RESOURCE_TYPE_CPU &&
      (resource_flavor == FLAVOR_CPU_MONITOR ||
       resource_flavor == FLAVOR_CPU_MONITOR_FATAL)) {
    // These exceptions may be fatal. They are not fatal by default at task
    // creation but can be made fatal by calling proc_rlimit_control() with
    // RLIMIT_CPU_USAGE_MONITOR as the second argument and CPUMON_MAKE_FATAL set
    // in the flags.
    if (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 ||
        MacOSVersionNumber() >= 10'10'00) {
      // In OS X 10.10, the exception code indicates whether the exception is
      // fatal. See 10.10 xnu-2782.1.97/osfmk/kern/thread.c
      // THIS_THREAD_IS_CONSUMING_TOO_MUCH_CPU__SENDING_EXC_RESOURCE().
      return resource_flavor == FLAVOR_CPU_MONITOR;
    }

    // In OS X 10.9, there’s no way to determine whether the exception is fatal.
    // Unlike RESOURCE_TYPE_WAKEUPS below, there’s no way to determine this
    // outside the kernel. proc_rlimit_control()’s RLIMIT_CPU_USAGE_MONITOR is
    // the only interface to modify CPUMON_MAKE_FATAL, but it’s only able to set
    // this bit, not obtain its current value.
    //
    // Default to assuming that these exceptions are nonfatal. They are nonfatal
    // by default and no users of proc_rlimit_control() were found on 10.9.5
    // 13F1066 in /System and /usr outside of Metadata.framework and associated
    // tools.
    return true;
  }

  if (resource_type == RESOURCE_TYPE_WAKEUPS &&
      resource_flavor == FLAVOR_WAKEUPS_MONITOR) {
    // These exceptions may be fatal. They are not fatal by default at task
    // creation, but can be made fatal by calling proc_rlimit_control() with
    // RLIMIT_WAKEUPS_MONITOR as the second argument and WAKEMON_MAKE_FATAL set
    // in the flags.
    //
    // proc_get_wakemon_params() (which calls
    // through to proc_rlimit_control() with RLIMIT_WAKEUPS_MONITOR) determines
    // whether these exceptions are fatal. See 10.10
    // xnu-2782.1.97/osfmk/kern/task.c
    // THIS_PROCESS_IS_CAUSING_TOO_MANY_WAKEUPS__SENDING_EXC_RESOURCE().
    //
    // If proc_get_wakemon_params() fails, default to assuming that these
    // exceptions are nonfatal. They are nonfatal by default and no users of
    // proc_rlimit_control() were found on 10.9.5 13F1066 in /System and /usr
    // outside of Metadata.framework and associated tools.
    int wm_rate;
    int wm_flags;
    int rv = ProcGetWakemonParams(pid, &wm_rate, &wm_flags);
    if (rv < 0) {
      PLOG(WARNING) << "ProcGetWakemonParams";
      return true;
    }

    return !(wm_flags & WAKEMON_MAKE_FATAL);
  }

  if (resource_type == RESOURCE_TYPE_MEMORY &&
      resource_flavor == FLAVOR_HIGH_WATERMARK) {
    // These exceptions were never fatal prior to 10.12. See 10.10
    // xnu-2782.1.97/osfmk/kern/task.c
    // THIS_PROCESS_CROSSED_HIGH_WATERMARK__SENDING_EXC_RESOURCE().
    //
    // A superficial examination of 10.12 shows that these exceptions may be
    // fatal, as determined by the P_MEMSTAT_FATAL_MEMLIMIT bit of the
    // kernel-internal struct proc::p_memstat_state. See 10.12.3
    // xnu-3789.41.3/osfmk/kern/task.c task_footprint_exceeded(). This bit is
    // not exposed to user space, which makes it difficult to determine whether
    // the kernel considers a given instance of this exception fatal. However, a
    // close read reveals that it is only possible for this bit to become set
    // when xnu-3789.41.3/bsd/kern/kern_memorystatus.c
    // memorystatus_cmd_set_memlimit_properties() is called, which is only
    // possible when the kernel is built with CONFIG_JETSAM set, or if the
    // kern.memorystatus_highwater_enabled sysctl is used, which is only
    // possible when the kernel is built with DEVELOPMENT or DEBUG set. Although
    // CONFIG_JETSAM is used on iOS, it is not used on macOS. DEVELOPMENT and
    // DEBUG are also not set for production kernels. It therefore remains
    // impossible for these exceptions to be fatal, even on 10.12.
    return true;
  }

  if (resource_type == RESOURCE_TYPE_IO) {
    // These exceptions are never fatal. See 10.12.3
    // xnu-3789.41.3/osfmk/kern/task.c
    // SENDING_NOTIFICATION__THIS_PROCESS_IS_CAUSING_TOO_MUCH_IO().
    return true;
  }

  // Treat unknown exceptions as fatal. This is the conservative approach: it
  // may result in more crash reports being generated, but the type-flavor
  // combinations can be evaluated to determine appropriate handling.
  LOG(WARNING) << "unknown resource type " << resource_type << " flavor "
               << resource_flavor;
  return false;
}

}  // namespace crashpad
