/* Copyright (c) 2018, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "abi_test.h"

#include <stdarg.h>
#include <stdio.h>

#include <algorithm>
#include <array>

#include <openssl/buf.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/span.h>

#if defined(OPENSSL_LINUX) && defined(SUPPORTS_ABI_TEST) && \
    defined(BORINGSSL_HAVE_LIBUNWIND)
#define UNWIND_TEST_SIGTRAP

#define UNW_LOCAL_ONLY
#include <errno.h>
#include <fcntl.h>
#include <libunwind.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif  // LINUX && SUPPORTS_ABI_TEST && HAVE_LIBUNWIND


namespace abi_test {

namespace internal {

static bool g_unwind_tests_enabled = false;

std::string FixVAArgsString(const char *str) {
  std::string ret = str;
  size_t idx = ret.find(',');
  if (idx == std::string::npos) {
    return ret + "()";
  }
  size_t idx2 = idx + 1;
  while (idx2 < ret.size() && ret[idx2] == ' ') {
    idx2++;
  }
  while (idx > 0 && ret[idx - 1] == ' ') {
    idx--;
  }
  return ret.substr(0, idx) + "(" + ret.substr(idx2) + ")";
}

#if defined(SUPPORTS_ABI_TEST)
// ForEachMismatch calls |func| for each register where |a| and |b| differ.
template <typename Func>
static void ForEachMismatch(const CallerState &a, const CallerState &b,
                            const Func &func) {
#define CALLER_STATE_REGISTER(type, name) \
  if (a.name != b.name) {                 \
    func(#name);                          \
  }
  LOOP_CALLER_STATE_REGISTERS()
#undef CALLER_STATE_REGISTER
}

// ReadUnwindResult adds the results of the most recent unwind test to |out|.
static void ReadUnwindResult(Result *out);

crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
                            const crypto_word_t *argv, size_t argc,
                            bool unwind) {
  CallerState state;
  RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));

  unwind &= g_unwind_tests_enabled;
  CallerState state2 = state;
  crypto_word_t ret = abi_test_trampoline(func, &state2, argv, argc, unwind);
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
  // Query and clear the direction flag early, so negative tests do not
  // interfere with |malloc|.
  bool direction_flag = abi_test_get_and_clear_direction_flag();
#endif  // OPENSSL_X86_64 || OPENSSL_X86

  *out = Result();
  ForEachMismatch(state, state2, [&](const char *reg) {
    out->errors.push_back(std::string(reg) + " was not restored after return");
  });
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
  // Linux and Windows ABIs for x86 require the direction flag be cleared on
  // return. (Some OpenSSL assembly preserves it, which is stronger, but we only
  // require what is specified by the ABI so |CHECK_ABI| works with C compiler
  // output.)
  if (direction_flag) {
    out->errors.emplace_back("Direction flag set after return");
  }
#endif  // OPENSSL_X86_64 || OPENSSL_X86
  if (unwind) {
    ReadUnwindResult(out);
  }
  return ret;
}
#endif  // SUPPORTS_ABI_TEST

#if defined(UNWIND_TEST_SIGTRAP)
// On Linux, we test unwind metadata using libunwind and |SIGTRAP|. We run the
// function under test with the trap flag set. This results in |SIGTRAP|s on
// every instruction. We then handle these signals and verify with libunwind.

// HandleEINTR runs |func| and returns the result, retrying the operation on
// |EINTR|.
template <typename Func>
static auto HandleEINTR(const Func &func) -> decltype(func()) {
  decltype(func()) ret;
  do {
    ret = func();
  } while (ret < 0 && errno == EINTR);
  return ret;
}

static bool ReadFileToString(std::string *out, const char *path) {
  out->clear();

  int fd = HandleEINTR([&] { return open(path, O_RDONLY); });
  if (fd < 0) {
    return false;
  }

  for (;;) {
    char buf[1024];
    ssize_t ret = HandleEINTR([&] { return read(fd, buf, sizeof(buf)); });
    if (ret < 0) {
      close(fd);
      return false;
    }
    if (ret == 0) {
      close(fd);
      return true;
    }
    out->append(buf, static_cast<size_t>(ret));
  }
}

static bool IsBeingDebugged() {
  std::string status;
  if (!ReadFileToString(&status, "/proc/self/status")) {
    perror("error reading /proc/self/status");
    return false;
  }
  std::string key = "\nTracerPid:\t";
  size_t idx = status.find(key);
  if (idx == std::string::npos) {
    return false;
  }
  idx += key.size();
  return idx < status.size() && status[idx] != '0';
}

// IsAncestorStackFrame returns true if |a_sp| is an ancestor stack frame of
// |b_sp|.
static bool IsAncestorStackFrame(unw_word_t a_sp, unw_word_t b_sp) {
#if defined(OPENSSL_X86_64)
  // The stack grows down, so ancestor stack frames have higher addresses.
  return a_sp > b_sp;
#else
#error "unknown architecture"
#endif
}

static int CallerStateFromUNWCursor(CallerState *out, unw_cursor_t *cursor) {
  // |CallerState| uses |crypto_word_t|, while libunwind uses |unw_word_t|, but
  // both are defined as |uint*_t| from stdint.h, so we can assume the types
  // match.
#if defined(OPENSSL_X86_64)
  int ret = 0;
  ret = ret < 0 ? ret : unw_get_reg(cursor, UNW_X86_64_RBX, &out->rbx);
  ret = ret < 0 ? ret : unw_get_reg(cursor, UNW_X86_64_RBP, &out->rbp);
  ret = ret < 0 ? ret : unw_get_reg(cursor, UNW_X86_64_R12, &out->r12);
  ret = ret < 0 ? ret : unw_get_reg(cursor, UNW_X86_64_R13, &out->r13);
  ret = ret < 0 ? ret : unw_get_reg(cursor, UNW_X86_64_R14, &out->r14);
  ret = ret < 0 ? ret : unw_get_reg(cursor, UNW_X86_64_R15, &out->r15);
  return ret;
#else
#error "unknown architecture"
#endif
}

// Implement some string formatting utilties. Ideally we would use |snprintf|,
// but this is called in a signal handler and |snprintf| is not async-signal-
// safe.

static std::array<char, DECIMAL_SIZE(unw_word_t) + 1> WordToDecimal(
    unw_word_t v) {
  std::array<char, DECIMAL_SIZE(unw_word_t) + 1> ret;
  size_t len = 0;
  do {
    ret[len++] = '0' + v % 10;
    v /= 10;
  } while (v != 0);
  for (size_t i = 0; i < len / 2; i++) {
    std::swap(ret[i], ret[len - 1 - i]);
  }
  ret[len] = '\0';
  return ret;
}

static std::array<char, sizeof(unw_word_t) * 2 + 1> WordToHex(unw_word_t v) {
  static const char kHex[] = "0123456789abcdef";
  std::array<char, sizeof(unw_word_t) * 2 + 1> ret;
  for (size_t i = sizeof(unw_word_t) - 1; i < sizeof(unw_word_t); i--) {
    uint8_t b = v & 0xff;
    v >>= 8;
    ret[i * 2] = kHex[b >> 4];
    ret[i * 2 + 1] = kHex[b & 0xf];
  }
  ret[sizeof(unw_word_t) * 2] = '\0';
  return ret;
}

static void StrCatSignalSafeImpl(bssl::Span<char> out) {}

template <typename... Args>
static void StrCatSignalSafeImpl(bssl::Span<char> out, const char *str,
                                 Args... args) {
  BUF_strlcat(out.data(), str, out.size());
  StrCatSignalSafeImpl(out, args...);
}

template <typename... Args>
static void StrCatSignalSafe(bssl::Span<char> out, Args... args) {
  if (out.empty()) {
    return;
  }
  out[0] = '\0';
  StrCatSignalSafeImpl(out, args...);
}

static int UnwindToSignalFrame(unw_cursor_t *cursor) {
  for (;;) {
    int ret = unw_is_signal_frame(cursor);
    if (ret < 0) {
      return ret;
    }
    if (ret != 0) {
      return 0;  // Found the signal frame.
    }
    ret = unw_step(cursor);
    if (ret < 0) {
      return ret;
    }
  }
}

// IPToString returns a human-readable representation of |ip|, using debug
// information from |ctx| if available. |ip| must be the address of |ctx|'s
// signal frame. This function is async-signal-safe.
static std::array<char, 256> IPToString(unw_word_t ip, unw_context_t *ctx) {
  std::array<char, 256> ret;
  // Use a new cursor. The caller's cursor has already been unwound, but
  // |unw_get_proc_name| is slow so we do not wish to call it all the time.
  unw_cursor_t cursor;
  // Work around a bug in libunwind. See
  // https://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=commit;h=819bf51bbd2da462c2ec3401e8ac9153b6e725e3
  OPENSSL_memset(&cursor, 0, sizeof(cursor));
  unw_word_t off;
  if (unw_init_local(&cursor, ctx) != 0 ||
      UnwindToSignalFrame(&cursor) != 0 ||
      unw_get_proc_name(&cursor, ret.data(), ret.size(), &off) != 0) {
    StrCatSignalSafe(bssl::MakeSpan(ret), "0x", WordToHex(ip).data());
    return ret;
  }
  size_t len = strlen(ret.data());
  // Print the offset in decimal, to match gdb's disassembly output and ease
  // debugging.
  StrCatSignalSafe(bssl::MakeSpan(ret).subspan(len), "+",
                   WordToDecimal(off).data(), " (0x", WordToHex(ip).data(),
                   ")");
  return ret;
}

static pthread_t g_main_thread;

// g_in_trampoline is true if we are in an instrumented |abi_test_trampoline|
// call, in the region that triggers |SIGTRAP|.
static bool g_in_trampoline = false;
// g_unwind_function_done, if |g_in_trampoline| is true, is whether the function
// under test has returned. It is undefined otherwise.
static bool g_unwind_function_done;
// g_trampoline_state, if |g_in_trampoline| is true, is the state the function
// under test must preserve. It is undefined otherwise.
static CallerState g_trampoline_state;
// g_trampoline_sp, if |g_in_trampoline| is true, is the stack pointer of the
// trampoline frame. It is undefined otherwise.
static unw_word_t g_trampoline_sp;

// kMaxUnwindErrors is the maximum number of unwind errors reported per
// function. If a function's unwind tables are wrong, we are otherwise likely to
// repeat the same error at multiple addresses.
static constexpr size_t kMaxUnwindErrors = 10;

// Errors are saved in a signal handler. We use a static buffer to avoid
// allocation.
static size_t num_unwind_errors = 0;
static char unwind_errors[kMaxUnwindErrors][512];

template <typename... Args>
static void AddUnwindError(Args... args) {
  if (num_unwind_errors >= kMaxUnwindErrors) {
    return;
  }
  StrCatSignalSafe(unwind_errors[num_unwind_errors], args...);
  num_unwind_errors++;
}

template <typename... Args>
[[noreturn]] static void FatalError(Args... args) {
  // We cannot use |snprintf| here because it is not async-signal-safe.
  char buf[512];
  StrCatSignalSafe(buf, args..., "\n");
  write(STDERR_FILENO, buf, strlen(buf));
  abort();
}

static void TrapHandler(int sig) {
  // Note this is a signal handler, so only async-signal-safe functions may be
  // used here. See signal-safety(7). libunwind promises local unwind is
  // async-signal-safe.

  // |pthread_equal| is not listed as async-signal-safe, but this is clearly an
  // oversight.
  if (!pthread_equal(g_main_thread, pthread_self())) {
    FatalError("SIGTRAP on background thread");
  }

  unw_context_t ctx;
  int ret = unw_getcontext(&ctx);
  unw_cursor_t cursor;
  // Work around a bug in libunwind which breaks rax and rdx recovery. This
  // breaks functions which temporarily use rax as the CFA register. See
  // https://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=commit;h=819bf51bbd2da462c2ec3401e8ac9153b6e725e3
  OPENSSL_memset(&cursor, 0, sizeof(cursor));
  ret = ret < 0 ? ret : unw_init_local(&cursor, &ctx);
  ret = ret < 0 ? ret : UnwindToSignalFrame(&cursor);
  unw_word_t sp, ip;
  ret = ret < 0 ? ret : unw_get_reg(&cursor, UNW_REG_SP, &sp);
  ret = ret < 0 ? ret : unw_get_reg(&cursor, UNW_REG_IP, &ip);
  if (ret < 0) {
    FatalError("Error initializing unwind cursor: ", unw_strerror(ret));
  }

  const unw_word_t kStartAddress =
      reinterpret_cast<unw_word_t>(&abi_test_unwind_start);
  const unw_word_t kReturnAddress =
      reinterpret_cast<unw_word_t>(&abi_test_unwind_return);
  const unw_word_t kStopAddress =
      reinterpret_cast<unw_word_t>(&abi_test_unwind_stop);
  if (!g_in_trampoline) {
    if (ip != kStartAddress) {
      FatalError("Unexpected SIGTRAP at ", IPToString(ip, &ctx).data());
    }

    // Save the current state and begin.
    g_in_trampoline = true;
    g_unwind_function_done = false;
    g_trampoline_sp = sp;
    ret = CallerStateFromUNWCursor(&g_trampoline_state, &cursor);
    if (ret < 0) {
      FatalError("Error getting initial caller state: ", unw_strerror(ret));
    }
  } else {
    if (sp == g_trampoline_sp || g_unwind_function_done) {
      // |g_unwind_function_done| should imply |sp| is |g_trampoline_sp|, but
      // clearing the trap flag in x86 briefly displaces the stack pointer.
      //
      // Also note we check both |ip| and |sp| below, in case the function under
      // test is also |abi_test_trampoline|.
      if (ip == kReturnAddress && sp == g_trampoline_sp) {
        g_unwind_function_done = true;
      }
      if (ip == kStopAddress && sp == g_trampoline_sp) {
        // |SIGTRAP| is fatal again.
        g_in_trampoline = false;
      }
    } else if (IsAncestorStackFrame(sp, g_trampoline_sp)) {
      // This should never happen. We went past |g_trampoline_sp| without
      // stopping at |kStopAddress|.
      AddUnwindError("stack frame is before caller at ",
                     IPToString(ip, &ctx).data());
      g_in_trampoline = false;
    } else if (num_unwind_errors < kMaxUnwindErrors) {
      for (;;) {
        ret = unw_step(&cursor);
        if (ret < 0) {
          AddUnwindError("error unwinding from ", IPToString(ip, &ctx).data(),
                         ": ", unw_strerror(ret));
          break;
        }
        if (ret == 0) {
          AddUnwindError("could not unwind to starting frame from ",
                         IPToString(ip, &ctx).data());
          break;
        }

        unw_word_t cur_sp;
        ret = unw_get_reg(&cursor, UNW_REG_SP, &cur_sp);
        if (ret < 0) {
          AddUnwindError("error recovering stack pointer unwinding from ",
                         IPToString(ip, &ctx).data(), ": ", unw_strerror(ret));
          break;
        }
        if (IsAncestorStackFrame(cur_sp, g_trampoline_sp)) {
          AddUnwindError("unwound past starting frame from ",
                         IPToString(ip, &ctx).data());
          break;
        }
        if (cur_sp == g_trampoline_sp) {
          // We found the parent frame. Check the return address.
          unw_word_t cur_ip;
          ret = unw_get_reg(&cursor, UNW_REG_IP, &cur_ip);
          if (ret < 0) {
            AddUnwindError("error recovering return address unwinding from ",
                           IPToString(ip, &ctx).data(), ": ",
                           unw_strerror(ret));
          } else if (cur_ip != kReturnAddress) {
            AddUnwindError("wrong return address unwinding from ",
                           IPToString(ip, &ctx).data());
          }

          // Check the remaining registers.
          CallerState state;
          ret = CallerStateFromUNWCursor(&state, &cursor);
          if (ret < 0) {
            AddUnwindError("error recovering registers unwinding from ",
                           IPToString(ip, &ctx).data(), ": ",
                           unw_strerror(ret));
          } else {
            ForEachMismatch(state, g_trampoline_state, [&](const char *reg) {
              AddUnwindError(reg, " was not recovered unwinding from ",
                             IPToString(ip, &ctx).data());
            });
          }
          break;
        }
      }
    }
  }
}

static void ReadUnwindResult(Result *out) {
  for (size_t i = 0; i < num_unwind_errors; i++) {
    out->errors.emplace_back(unwind_errors[i]);
  }
  if (num_unwind_errors == kMaxUnwindErrors) {
    out->errors.emplace_back("(additional errors omitted)");
  }
  num_unwind_errors = 0;
}

static void EnableUnwindTestsImpl() {
  if (IsBeingDebugged()) {
    // Unwind tests drive logic via |SIGTRAP|, which conflicts with debuggers.
    fprintf(stderr, "Debugger detected. Disabling unwind tests.\n");
    return;
  }

  g_main_thread = pthread_self();

  struct sigaction trap_action;
  OPENSSL_memset(&trap_action, 0, sizeof(trap_action));
  sigemptyset(&trap_action.sa_mask);
  trap_action.sa_handler = TrapHandler;
  if (sigaction(SIGTRAP, &trap_action, NULL) != 0) {
    perror("sigaction");
    abort();
  }

  g_unwind_tests_enabled = true;
}

#else
// TODO(davidben): Implement an SEH-based unwind-tester.
#if defined(SUPPORTS_ABI_TEST)
static void ReadUnwindResult(Result *) {}
#endif
static void EnableUnwindTestsImpl() {}
#endif  // UNWIND_TEST_SIGTRAP

}  // namespace internal

void EnableUnwindTests() { internal::EnableUnwindTestsImpl(); }

bool UnwindTestsEnabled() { return internal::g_unwind_tests_enabled; }

}  // namespace abi_test
