// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#include "base/debug/leak_annotations.h"
#include "base/files/file_util.h"
#include "base/posix/eintr_wrapper.h"
#include "base/third_party/valgrind/valgrind.h"
#include "build/build_config.h"
#include "sandbox/linux/tests/unit_tests.h"

// Specifically, PNaCl toolchain does not have this flag.
#if !defined(POLLRDHUP)
#define POLLRDHUP 0x2000
#endif

namespace {
std::string TestFailedMessage(const std::string& msg) {
  return msg.empty() ? std::string() : "Actual test failure: " + msg;
}

int GetSubProcessTimeoutTimeInSeconds() {
#ifdef NDEBUG
  // Chromecast build lab devices need this much time to complete.
  // They only run in release.
  return 30;
#else
  // Want a shorter timeout than test runner to get a useful callstack
  // in debug.
  return 10;
#endif
}

// Returns the number of threads of the current process or -1.
int CountThreads() {
  struct stat task_stat;
  int task_d = stat("/proc/self/task", &task_stat);
  // task_stat.st_nlink should be the number of tasks + 2 (accounting for
  // "." and "..".
  if (task_d != 0 || task_stat.st_nlink < 3)
    return -1;
  const int num_threads = task_stat.st_nlink - 2;
  return num_threads;
}

}  // namespace

namespace sandbox {

bool IsAndroid() {
#if defined(OS_ANDROID)
  return true;
#else
  return false;
#endif
}

bool IsArchitectureArm() {
#if defined(ARCH_CPU_ARM_FAMILY)
  return true;
#else
  return false;
#endif
}

// TODO(jln): figure out why base/.../dynamic_annotations.h's
// RunningOnValgrind() cannot link.
bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; }

static const int kExpectedValue = 42;
static const int kIgnoreThisTest = 43;
static const int kExitWithAssertionFailure = 1;
#if !defined(OS_NACL_NONSFI)
static const int kExitForTimeout = 2;
#endif

#if defined(SANDBOX_USES_BASE_TEST_SUITE)
// This is due to StackDumpSignalHandler() performing _exit(1).
// TODO(jln): get rid of the collision with kExitWithAssertionFailure.
const int kExitAfterSIGSEGV = 1;
#endif

// PNaCl toolchain's signal ABIs are incompatible with Linux's.
// So, for simplicity, just drop the "timeout" feature from unittest framework
// with relying on the buildbot's timeout feature.
#if !defined(OS_NACL_NONSFI)
static void SigAlrmHandler(int) {
  const char failure_message[] = "Timeout reached!\n";
  // Make sure that we never block here.
  if (!fcntl(2, F_SETFL, O_NONBLOCK)) {
    ignore_result(write(2, failure_message, sizeof(failure_message) - 1));
  }
  _exit(kExitForTimeout);
}

// Set a timeout with a handler that will automatically fail the
// test.
static void SetProcessTimeout(int time_in_seconds) {
  struct sigaction act = {};
  act.sa_handler = SigAlrmHandler;
  SANDBOX_ASSERT(sigemptyset(&act.sa_mask) == 0);
  act.sa_flags = 0;

  struct sigaction old_act;
  SANDBOX_ASSERT(sigaction(SIGALRM, &act, &old_act) == 0);

  // We don't implemenet signal chaining, so make sure that nothing else
  // is expecting to handle SIGALRM.
  SANDBOX_ASSERT((old_act.sa_flags & SA_SIGINFO) == 0);
  SANDBOX_ASSERT(old_act.sa_handler == SIG_DFL);
  sigset_t sigalrm_set;
  SANDBOX_ASSERT(sigemptyset(&sigalrm_set) == 0);
  SANDBOX_ASSERT(sigaddset(&sigalrm_set, SIGALRM) == 0);
  SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK, &sigalrm_set, NULL) == 0);
  SANDBOX_ASSERT(alarm(time_in_seconds) == 0);  // There should be no previous
                                                // alarm.
}
#endif  // !defined(OS_NACL_NONSFI)

// Runs a test in a sub-process. This is necessary for most of the code
// in the BPF sandbox, as it potentially makes global state changes and as
// it also tends to raise fatal errors, if the code has been used in an
// insecure manner.
void UnitTests::RunTestInProcess(SandboxTestRunner* test_runner,
                                 DeathCheck death,
                                 const void* death_aux) {
  CHECK(test_runner);
  // We need to fork(), so we can't be multi-threaded, as threads could hold
  // locks.
  int num_threads = CountThreads();
#if !defined(THREAD_SANITIZER)
  const int kNumExpectedThreads = 1;
#else
  // Under TSAN, there is a special helper thread. It should be completely
  // invisible to our testing, so we ignore it. It should be ok to fork()
  // with this thread. It's currently buggy, but it's the best we can do until
  // there is a way to delay the start of the thread
  // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19).
  const int kNumExpectedThreads = 2;
#endif

  // The kernel is at liberty to wake a thread id futex before updating /proc.
  // If another test running in the same process has stopped a thread, it may
  // appear as still running in /proc.
  // We poll /proc, with an exponential back-off. At most, we'll sleep around
  // 2^iterations nanoseconds in nanosleep().
  for (unsigned int iteration = 0; iteration < 30; iteration++) {
    struct timespec ts = {0, 1L << iteration /* nanoseconds */};
    PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts)));
    num_threads = CountThreads();
    if (kNumExpectedThreads == num_threads)
      break;
  }

  ASSERT_EQ(kNumExpectedThreads, num_threads)
      << "Running sandbox tests with multiple threads "
      << "is not supported and will make the tests flaky.";
  int fds[2];
  ASSERT_EQ(0, pipe(fds));
  // Check that our pipe is not on one of the standard file descriptor.
  SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2);

  pid_t pid;
  ASSERT_LE(0, (pid = fork()));
  if (!pid) {
    // In child process
    // Redirect stderr to our pipe. This way, we can capture all error
    // messages, if we decide we want to do so in our tests.
    SANDBOX_ASSERT(dup2(fds[1], 2) == 2);
    SANDBOX_ASSERT(!close(fds[0]));
    SANDBOX_ASSERT(!close(fds[1]));

    // Don't set a timeout if running on Valgrind, since it's generally much
    // slower.
    if (!IsRunningOnValgrind()) {
#if !defined(OS_NACL_NONSFI)
      SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
#endif
    }

    // Disable core files. They are not very useful for our individual test
    // cases.
    struct rlimit no_core = {0};
    setrlimit(RLIMIT_CORE, &no_core);

    test_runner->Run();
    if (test_runner->ShouldCheckForLeaks()) {
#if defined(LEAK_SANITIZER)
      __lsan_do_leak_check();
#endif
    }
    _exit(kExpectedValue);
  }

  close(fds[1]);
  std::vector<char> msg_buf;
  ssize_t rc;

  // Make sure read() will never block as we'll use poll() to
  // block with a timeout instead.
  const int fcntl_ret = fcntl(fds[0], F_SETFL, O_NONBLOCK);
  ASSERT_EQ(0, fcntl_ret);
  struct pollfd poll_fd = {fds[0], POLLIN | POLLRDHUP, 0};

  int poll_ret;
  // We prefer the SIGALRM timeout to trigger in the child than this timeout
  // so we double the common value here.
  int poll_timeout = GetSubProcessTimeoutTimeInSeconds() * 2 * 1000;
  while ((poll_ret = poll(&poll_fd, 1, poll_timeout) > 0)) {
    const size_t kCapacity = 256;
    const size_t len = msg_buf.size();
    msg_buf.resize(len + kCapacity);
    rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity));
    msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0)));
    if (rc <= 0)
      break;
  }
  ASSERT_NE(poll_ret, -1) << "poll() failed";
  ASSERT_NE(poll_ret, 0) << "Timeout while reading child state";
  close(fds[0]);
  std::string msg(msg_buf.begin(), msg_buf.end());

  int status = 0;
  int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0));
  ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg);

  // At run-time, we sometimes decide that a test shouldn't actually
  // run (e.g. when testing sandbox features on a kernel that doesn't
  // have sandboxing support). When that happens, don't attempt to
  // call the "death" function, as it might be looking for a
  // death-test condition that would never have triggered.
  if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest ||
      !msg.empty()) {
    // We use gtest's ASSERT_XXX() macros instead of the DeathCheck
    // functions.  This means, on failure, "return" is called. This
    // only works correctly, if the call of the "death" callback is
    // the very last thing in our function.
    death(status, msg, death_aux);
  }
}

void UnitTests::DeathSuccess(int status, const std::string& msg, const void*) {
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details;
  bool subprocess_exited_but_printed_messages = !msg.empty();
  EXPECT_FALSE(subprocess_exited_but_printed_messages) << details;
}

void UnitTests::DeathSuccessAllowNoise(int status,
                                       const std::string& msg,
                                       const void*) {
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details;
}

void UnitTests::DeathMessage(int status,
                             const std::string& msg,
                             const void* aux) {
  std::string details(TestFailedMessage(msg));
  const char* expected_msg = static_cast<const char*>(aux);

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << "Exit status: " << status
                                              << " " << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(1, subprocess_exit_status) << details;

  bool subprocess_exited_without_matching_message =
      msg.find(expected_msg) == std::string::npos;

// In official builds CHECK messages are dropped, so look for SIGABRT.
// See https://code.google.com/p/chromium/issues/detail?id=437312
#if defined(OFFICIAL_BUILD) && defined(NDEBUG) && !defined(OS_ANDROID)
  if (subprocess_exited_without_matching_message) {
    static const char kSigAbortMessage[] = "Received signal 6";
    subprocess_exited_without_matching_message =
        msg.find(kSigAbortMessage) == std::string::npos;
  }
#endif
  EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
}

void UnitTests::DeathSEGVMessage(int status,
                                 const std::string& msg,
                                 const void* aux) {
  std::string details(TestFailedMessage(msg));
  const char* expected_msg = static_cast<const char*>(aux);

#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
  const bool subprocess_got_sigsegv =
      WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status));
#else
  // This hack is required when a signal handler is installed
  // for SEGV that will _exit(1).
  const bool subprocess_got_sigsegv =
      WIFEXITED(status) && (kExitAfterSIGSEGV == WEXITSTATUS(status));
#endif

  ASSERT_TRUE(subprocess_got_sigsegv) << "Exit status: " << status
                                      << " " << details;

  bool subprocess_exited_without_matching_message =
      msg.find(expected_msg) == std::string::npos;
  EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
}

void UnitTests::DeathExitCode(int status,
                              const std::string& msg,
                              const void* aux) {
  int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux));
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_normally = WIFEXITED(status);
  ASSERT_TRUE(subprocess_terminated_normally) << details;
  int subprocess_exit_status = WEXITSTATUS(status);
  ASSERT_EQ(expected_exit_code, subprocess_exit_status) << details;
}

void UnitTests::DeathBySignal(int status,
                              const std::string& msg,
                              const void* aux) {
  int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux));
  std::string details(TestFailedMessage(msg));

  bool subprocess_terminated_by_signal = WIFSIGNALED(status);
  ASSERT_TRUE(subprocess_terminated_by_signal) << details;
  int subprocess_signal_number = WTERMSIG(status);
  ASSERT_EQ(expected_signo, subprocess_signal_number) << details;
}

void UnitTests::AssertionFailure(const char* expr, const char* file, int line) {
  fprintf(stderr, "%s:%d:%s", file, line, expr);
  fflush(stderr);
  _exit(kExitWithAssertionFailure);
}

void UnitTests::IgnoreThisTest() {
  fflush(stderr);
  _exit(kIgnoreThisTest);
}

}  // namespace
