// 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
#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
