// Copyright 2018 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 "src/trap-handler/handler-inside-posix.h"

#include <signal.h>

#if defined(V8_OS_LINUX) || defined(V8_OS_FREEBSD)
#include <ucontext.h>
#elif V8_OS_MACOSX
#include <sys/ucontext.h>
#endif

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

bool IsKernelGeneratedSignal(siginfo_t* info) {
  // On macOS, only `info->si_code > 0` is relevant, because macOS leaves
  // si_code at its default of 0 for signals that don’t originate in hardware.
  // The other conditions are only relevant for Linux.
  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;
}

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_);
  }

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

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

 private:
  sigset_t old_mask_;
};

bool TryHandleSignal(int signum, siginfo_t* info, void* context) {
  // Ensure the faulting thread was actually running Wasm code. This should be
  // the first check in the trap handler to guarantee that the IsThreadInWasm
  // flag is only set in wasm code. Otherwise a later signal handler is executed
  // with the flag set.
  if (!IsThreadInWasm()) {
    return false;
  }

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

  // Bail out early in case we got called for the wrong kind of signal.

  if (signum != kOobSignal) {
    return false;
  }

  // Make sure the signal was generated by the kernel and not some other source.
  if (!IsKernelGeneratedSignal(info)) {
    return 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);

    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
#if V8_OS_LINUX
    auto* context_rip = &uc->uc_mcontext.gregs[REG_RIP];
#elif V8_OS_MACOSX
    auto* context_rip = &uc->uc_mcontext->__ss.__rip;
#elif V8_OS_FREEBSD
    auto* context_rip = &uc->uc_mcontext.mc_rip;
#else
#error Unsupported platform
#endif
    uintptr_t fault_addr = *context_rip;
    uintptr_t landing_pad = 0;
    if (TryFindLandingPad(fault_addr, &landing_pad)) {
      // Tell the caller to return to the landing pad.
      *context_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;
}

void HandleSignal(int signum, siginfo_t* info, void* context) {
  if (!TryHandleSignal(signum, info, context)) {
    // 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.
    RemoveTrapHandler();
    if (!IsKernelGeneratedSignal(info)) {
      raise(signum);
    }
  }
  // TryHandleSignal modifies context to change where we return to.
}

}  // namespace trap_handler
}  // namespace internal
}  // namespace v8
