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

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

int GetSubProcessTimeoutTimeInSeconds() {
  // 10s ought to be enough for anybody.
  return 10;
}

// 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;
static const int kExitForTimeout = 2;

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

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.
}

// 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()) {
      SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
    }

    // 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(OS_ANDROID)
  const bool subprocess_got_sigsegv =
      WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status));
#else
  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
