// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// PLEASE READ BEFORE CHANGING THIS FILE!
//
// This file implements the out of bounds signal handler for
// WebAssembly. Signal handlers are notoriously difficult to get
// right, and getting it wrong can lead to security
// vulnerabilities. In order to minimize this risk, here are some
// rules to follow.
//
// 1. Do not introduce any new external dependencies. This file needs
//    to be self contained so it is easy to audit everything that a
//    signal handler might do.
//
// 2. Any changes must be reviewed by someone from the crash reporting
//    or security team. See OWNERS for suggested reviewers.
//
// For more information, see https://goo.gl/yMeyUY.
//
// This file contains most of the code that actually runs in a signal handler
// context. Some additional code is used both inside and outside the signal
// handler. This code can be found in handler-shared.cc.

#include <signal.h>
#include <stddef.h>
#include <stdlib.h>

#include "src/trap-handler/trap-handler-internal.h"
#include "src/trap-handler/trap-handler.h"

namespace v8 {
namespace internal {
namespace trap_handler {

namespace {

bool IsKernelGeneratedSignal(siginfo_t* info) {
  return info->si_code > 0 && info->si_code != SI_USER &&
         info->si_code != SI_QUEUE && info->si_code != SI_TIMER &&
         info->si_code != SI_ASYNCIO && info->si_code != SI_MESGQ;
}

#if V8_TRAP_HANDLER_SUPPORTED
class SigUnmaskStack {
 public:
  explicit SigUnmaskStack(sigset_t sigs) {
    // TODO(eholk): consider using linux-syscall-support for calling this
    // syscall.
    pthread_sigmask(SIG_UNBLOCK, &sigs, &old_mask_);
  }

  ~SigUnmaskStack() { pthread_sigmask(SIG_SETMASK, &old_mask_, nullptr); }

 private:
  sigset_t old_mask_;

  // We'd normally use DISALLOW_COPY_AND_ASSIGN, but we're avoiding a dependency
  // on base/macros.h
  SigUnmaskStack(const SigUnmaskStack&) = delete;
  void operator=(const SigUnmaskStack&) = delete;
};
#endif
}  // namespace

#if V8_TRAP_HANDLER_SUPPORTED && V8_OS_LINUX && V8_TARGET_ARCH_X64 && \
    !V8_OS_ANDROID
#if defined(STARBOARD)
bool TryHandleSignal(int signum, siginfo_t* info, ucontext_t* context) {
  SB_NOTREACHED();
  return false;
}

bool TryFindLandingPad(uintptr_t fault_addr, uintptr_t* landing_pad) {
  SB_NOTREACHED()
  return false;
}
#else
bool TryHandleSignal(int signum, siginfo_t* info, ucontext_t* context) {
  // Bail out early in case we got called for the wrong kind of signal.
  if (signum != SIGSEGV) {
    return false;
  }

  // Make sure the signal was generated by the kernel and not some other source.
  if (!IsKernelGeneratedSignal(info)) {
    return false;
  }

  // Ensure the faulting thread was actually running Wasm code.
  if (!IsThreadInWasm()) {
    return false;
  }

  // Clear g_thread_in_wasm_code, primarily to protect against nested faults.
  g_thread_in_wasm_code = false;

  // Begin signal mask scope. We need to be sure to restore the signal mask
  // before we restore the g_thread_in_wasm_code flag.
  {
    // Unmask the signal so that if this signal handler crashes, the crash will
    // be handled by the crash reporter.  Otherwise, the process might be killed
    // with the crash going unreported.
    sigset_t sigs;
    // Fortunately, sigemptyset and sigaddset are async-signal-safe according to
    // the POSIX standard.
    sigemptyset(&sigs);
    sigaddset(&sigs, SIGSEGV);
    SigUnmaskStack unmask(sigs);

    uintptr_t fault_addr = context->uc_mcontext.gregs[REG_RIP];
    uintptr_t landing_pad = 0;
    if (TryFindLandingPad(fault_addr, &landing_pad)) {
      // Tell the caller to return to the landing pad.
      context->uc_mcontext.gregs[REG_RIP] = landing_pad;
      // We will return to wasm code, so restore the g_thread_in_wasm_code flag.
      g_thread_in_wasm_code = true;
      return true;
    }
  }  // end signal mask scope

  // If we get here, it's not a recoverable wasm fault, so we go to the next
  // handler. Leave the g_thread_in_wasm_code flag unset since we do not return
  // to wasm code.
  return false;
}

// This function contains the platform independent portions of fault
// classification.
bool TryFindLandingPad(uintptr_t fault_addr, uintptr_t* landing_pad) {
  // TODO(eholk): broad code range check

  // Taking locks in a signal handler is risky because a fault in the signal
  // handler could lead to a deadlock when attempting to acquire the lock
  // again. We guard against this case with g_thread_in_wasm_code. The lock
  // may only be taken when not executing Wasm code (an assert in
  // MetadataLock's constructor ensures this). This signal handler will bail
  // out before trying to take the lock if g_thread_in_wasm_code is not set.
  MetadataLock lock_holder;

  for (size_t i = 0; i < gNumCodeObjects; ++i) {
    const CodeProtectionInfo* data = gCodeObjects[i].code_info;
    if (data == nullptr) {
      continue;
    }
    const uintptr_t base = reinterpret_cast<uintptr_t>(data->base);

    if (fault_addr >= base && fault_addr < base + data->size) {
      // Hurray, we found the code object. Check for protected addresses.
      const ptrdiff_t offset = fault_addr - base;

      for (unsigned i = 0; i < data->num_protected_instructions; ++i) {
        if (data->instructions[i].instr_offset == offset) {
          // Hurray again, we found the actual instruction.
          *landing_pad = data->instructions[i].landing_offset + base;

          gRecoveredTrapCount.store(
              gRecoveredTrapCount.load(std::memory_order_relaxed) + 1,
              std::memory_order_relaxed);

          return true;
        }
      }
    }
  }
  return false;
}
#endif  // STARBOARD
#endif  // V8_TRAP_HANDLER_SUPPORTED && V8_OS_LINUX

#if V8_TRAP_HANDLER_SUPPORTED
void HandleSignal(int signum, siginfo_t* info, void* context) {
  ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);

  if (!TryHandleSignal(signum, info, uc)) {
    // Since V8 didn't handle this signal, we want to re-raise the same signal.
    // For kernel-generated SEGV signals, we do this by restoring the original
    // SEGV handler and then returning. The fault will happen again and the
    // usual SEGV handling will happen.
    //
    // We handle user-generated signals by calling raise() instead. This is for
    // completeness. We should never actually see one of these, but just in
    // case, we do the right thing.
    RestoreOriginalSignalHandler();
    if (!IsKernelGeneratedSignal(info)) {
      raise(signum);
    }
  }
  // TryHandleSignal modifies context to change where we return to.
}
#endif
}  // namespace trap_handler
}  // namespace internal
}  // namespace v8
