// Copyright (c) 2009, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// linux_ptrace_dumper_unittest.cc:
// Unit tests for google_breakpad::LinuxPtraceDumper.
//
// This file was renamed from linux_dumper_unittest.cc and modified due
// to LinuxDumper being splitted into two classes.

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <string>

#include "breakpad_googletest_includes.h"
#include "client/linux/minidump_writer/linux_ptrace_dumper.h"
#include "client/linux/minidump_writer/minidump_writer_unittest_utils.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/file_id.h"
#include "common/linux/ignore_ret.h"
#include "common/linux/safe_readlink.h"
#include "common/memory_allocator.h"
#include "common/using_std_string.h"

#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61
#endif

using namespace google_breakpad;

namespace {

pid_t SetupChildProcess(int number_of_threads) {
  char kNumberOfThreadsArgument[2];
  sprintf(kNumberOfThreadsArgument, "%d", number_of_threads);

  int fds[2];
  EXPECT_NE(-1, pipe(fds));

  pid_t child_pid = fork();
  if (child_pid == 0) {
    // In child process.
    close(fds[0]);

    string helper_path(GetHelperBinary());
    if (helper_path.empty()) {
      fprintf(stderr, "Couldn't find helper binary\n");
      _exit(1);
    }

    // Pass the pipe fd and the number of threads as arguments.
    char pipe_fd_string[8];
    sprintf(pipe_fd_string, "%d", fds[1]);
    execl(helper_path.c_str(),
          "linux_dumper_unittest_helper",
          pipe_fd_string,
          kNumberOfThreadsArgument,
          NULL);
    // Kill if we get here.
    printf("Errno from exec: %d", errno);
    std::string err_str = "Exec of  " + helper_path + " failed";
    perror(err_str.c_str());
    _exit(1);
  }
  close(fds[1]);

  // Wait for all child threads to indicate that they have started
  for (int threads = 0; threads < number_of_threads; threads++) {
    struct pollfd pfd;
    memset(&pfd, 0, sizeof(pfd));
    pfd.fd = fds[0];
    pfd.events = POLLIN | POLLERR;

    const int r = HANDLE_EINTR(poll(&pfd, 1, 1000));
    EXPECT_EQ(1, r);
    EXPECT_TRUE(pfd.revents & POLLIN);
    uint8_t junk;
    EXPECT_EQ(read(fds[0], &junk, sizeof(junk)),
              static_cast<ssize_t>(sizeof(junk)));
  }
  close(fds[0]);

  // There is a race here because we may stop a child thread before
  // it is actually running the busy loop. Empirically this sleep
  // is sufficient to avoid the race.
  usleep(100000);
  return child_pid;
}

typedef wasteful_vector<uint8_t> id_vector;
typedef testing::Test LinuxPtraceDumperTest;

/* Fixture for running tests in a child process. */
class LinuxPtraceDumperChildTest : public testing::Test {
 protected:
  virtual void SetUp() {
    child_pid_ = fork();
#ifndef __ANDROID__
    prctl(PR_SET_PTRACER, child_pid_);
#endif
  }

  /* Gtest is calling TestBody from this class, which sets up a child
   * process in which the RealTestBody virtual member is called.
   * As such, TestBody is not supposed to be overridden in derived classes.
   */
  virtual void TestBody() /* final */ {
    if (child_pid_ == 0) {
      // child process
      RealTestBody();
      exit(HasFatalFailure() ? kFatalFailure :
           (HasNonfatalFailure() ? kNonFatalFailure : 0));
    }

    ASSERT_TRUE(child_pid_ > 0);
    int status;
    waitpid(child_pid_, &status, 0);
    if (WEXITSTATUS(status) == kFatalFailure) {
      GTEST_FATAL_FAILURE_("Test failed in child process");
    } else if (WEXITSTATUS(status) == kNonFatalFailure) {
      GTEST_NONFATAL_FAILURE_("Test failed in child process");
    }
  }

  /* Gtest defines TestBody functions through its macros, but classes
   * derived from this one need to define RealTestBody instead.
   * This is achieved by defining a TestBody macro further below.
   */
  virtual void RealTestBody() = 0;

  id_vector make_vector() {
    return id_vector(&allocator, kDefaultBuildIdSize);
  }

 private:
  static const int kFatalFailure = 1;
  static const int kNonFatalFailure = 2;

  pid_t child_pid_;
  PageAllocator allocator;
};

}  // namespace

/* Replace TestBody declarations within TEST*() with RealTestBody
 * declarations */
#define TestBody RealTestBody

TEST_F(LinuxPtraceDumperChildTest, Setup) {
  LinuxPtraceDumper dumper(getppid());
}

TEST_F(LinuxPtraceDumperChildTest, FindMappings) {
  LinuxPtraceDumper dumper(getppid());
  ASSERT_TRUE(dumper.Init());

  ASSERT_TRUE(dumper.FindMapping(reinterpret_cast<void*>(getpid)));
  ASSERT_TRUE(dumper.FindMapping(reinterpret_cast<void*>(printf)));
  ASSERT_FALSE(dumper.FindMapping(NULL));
}

TEST_F(LinuxPtraceDumperChildTest, ThreadList) {
  LinuxPtraceDumper dumper(getppid());
  ASSERT_TRUE(dumper.Init());

  ASSERT_GE(dumper.threads().size(), (size_t)1);
  bool found = false;
  for (size_t i = 0; i < dumper.threads().size(); ++i) {
    if (dumper.threads()[i] == getppid()) {
      ASSERT_FALSE(found);
      found = true;
    }
  }
  ASSERT_TRUE(found);
}

// Helper stack class to close a file descriptor and unmap
// a mmap'ed mapping.
class StackHelper {
 public:
  StackHelper()
    : fd_(-1), mapping_(NULL), size_(0) {}
  ~StackHelper() {
    if (size_)
      munmap(mapping_, size_);
    if (fd_ >= 0)
      close(fd_);
  }
  void Init(int fd, char* mapping, size_t size) {
    fd_ = fd;
    mapping_ = mapping;
    size_ = size;
  }

  char* mapping() const { return mapping_; }
  size_t size() const { return size_; }

 private:
  int fd_;
  char* mapping_;
  size_t size_;
};

class LinuxPtraceDumperMappingsTest : public LinuxPtraceDumperChildTest {
 protected:
  virtual void SetUp();

  string helper_path_;
  size_t page_size_;
  StackHelper helper_;
};

void LinuxPtraceDumperMappingsTest::SetUp() {
  helper_path_ = GetHelperBinary();
  if (helper_path_.empty()) {
    FAIL() << "Couldn't find helper binary";
    exit(1);
  }

  // mmap two segments out of the helper binary, one
  // enclosed in the other, but with different protections.
  page_size_ = sysconf(_SC_PAGESIZE);
  const size_t kMappingSize = 3 * page_size_;
  int fd = open(helper_path_.c_str(), O_RDONLY);
  ASSERT_NE(-1, fd) << "Failed to open file: " << helper_path_
                    << ", Error: " << strerror(errno);
  char* mapping =
    reinterpret_cast<char*>(mmap(NULL,
                                 kMappingSize,
                                 PROT_READ,
                                 MAP_SHARED,
                                 fd,
                                 0));
  ASSERT_TRUE(mapping);

  // Ensure that things get cleaned up.
  helper_.Init(fd, mapping, kMappingSize);

  // Carve a page out of the first mapping with different permissions.
  char* inside_mapping =  reinterpret_cast<char*>(
      mmap(mapping + 2 * page_size_,
           page_size_,
           PROT_NONE,
           MAP_SHARED | MAP_FIXED,
           fd,
           // Map a different offset just to
           // better test real-world conditions.
           page_size_));
  ASSERT_TRUE(inside_mapping);

  LinuxPtraceDumperChildTest::SetUp();
}

TEST_F(LinuxPtraceDumperMappingsTest, MergedMappings) {
  // Now check that LinuxPtraceDumper interpreted the mappings properly.
  LinuxPtraceDumper dumper(getppid());
  ASSERT_TRUE(dumper.Init());
  int mapping_count = 0;
  for (unsigned i = 0; i < dumper.mappings().size(); ++i) {
    const MappingInfo& mapping = *dumper.mappings()[i];
    if (strcmp(mapping.name, this->helper_path_.c_str()) == 0) {
      // This mapping should encompass the entire original mapped
      // range.
      EXPECT_EQ(reinterpret_cast<uintptr_t>(this->helper_.mapping()),
                mapping.start_addr);
      EXPECT_EQ(this->helper_.size(), mapping.size);
      EXPECT_EQ(0U, mapping.offset);
      mapping_count++;
    }
  }
  EXPECT_EQ(1, mapping_count);
}

TEST_F(LinuxPtraceDumperChildTest, BuildProcPath) {
  const pid_t pid = getppid();
  LinuxPtraceDumper dumper(pid);

  char maps_path[NAME_MAX] = "";
  char maps_path_expected[NAME_MAX];
  snprintf(maps_path_expected, sizeof(maps_path_expected),
           "/proc/%d/maps", pid);
  EXPECT_TRUE(dumper.BuildProcPath(maps_path, pid, "maps"));
  EXPECT_STREQ(maps_path_expected, maps_path);

  EXPECT_FALSE(dumper.BuildProcPath(NULL, pid, "maps"));
  EXPECT_FALSE(dumper.BuildProcPath(maps_path, 0, "maps"));
  EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, ""));
  EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, NULL));

  char long_node[NAME_MAX];
  size_t long_node_len = NAME_MAX - strlen("/proc/123") - 1;
  memset(long_node, 'a', long_node_len);
  long_node[long_node_len] = '\0';
  EXPECT_FALSE(dumper.BuildProcPath(maps_path, 123, long_node));
}

#if !defined(__ARM_EABI__) && !defined(__mips__)
// Ensure that the linux-gate VDSO is included in the mapping list.
TEST_F(LinuxPtraceDumperChildTest, MappingsIncludeLinuxGate) {
  LinuxPtraceDumper dumper(getppid());
  ASSERT_TRUE(dumper.Init());

  void* linux_gate_loc =
    reinterpret_cast<void *>(dumper.auxv()[AT_SYSINFO_EHDR]);
  ASSERT_TRUE(linux_gate_loc);
  bool found_linux_gate = false;

  const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
  const MappingInfo* mapping;
  for (unsigned i = 0; i < mappings.size(); ++i) {
    mapping = mappings[i];
    if (!strcmp(mapping->name, kLinuxGateLibraryName)) {
      found_linux_gate = true;
      break;
    }
  }
  EXPECT_TRUE(found_linux_gate);
  EXPECT_EQ(linux_gate_loc, reinterpret_cast<void*>(mapping->start_addr));
  EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG));
}

// Ensure that the linux-gate VDSO can generate a non-zeroed File ID.
TEST_F(LinuxPtraceDumperChildTest, LinuxGateMappingID) {
  LinuxPtraceDumper dumper(getppid());
  ASSERT_TRUE(dumper.Init());

  bool found_linux_gate = false;
  const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
  unsigned index = 0;
  for (unsigned i = 0; i < mappings.size(); ++i) {
    if (!strcmp(mappings[i]->name, kLinuxGateLibraryName)) {
      found_linux_gate = true;
      index = i;
      break;
    }
  }
  ASSERT_TRUE(found_linux_gate);

  // Need to suspend the child so ptrace actually works.
  ASSERT_TRUE(dumper.ThreadsSuspend());
  id_vector identifier(make_vector());
  ASSERT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[index],
                                                 true,
                                                 index,
                                                 identifier));

  id_vector empty_identifier(make_vector());
  empty_identifier.resize(kDefaultBuildIdSize, 0);
  EXPECT_NE(empty_identifier, identifier);
  EXPECT_TRUE(dumper.ThreadsResume());
}
#endif

TEST_F(LinuxPtraceDumperChildTest, FileIDsMatch) {
  // Calculate the File ID of our binary using both
  // FileID::ElfFileIdentifier and LinuxDumper::ElfFileIdentifierForMapping
  // and ensure that we get the same result from both.
  char exe_name[PATH_MAX];
  ASSERT_TRUE(SafeReadLink("/proc/self/exe", exe_name));

  LinuxPtraceDumper dumper(getppid());
  ASSERT_TRUE(dumper.Init());
  const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
  bool found_exe = false;
  unsigned i;
  for (i = 0; i < mappings.size(); ++i) {
    const MappingInfo* mapping = mappings[i];
    if (!strcmp(mapping->name, exe_name)) {
      found_exe = true;
      break;
    }
  }
  ASSERT_TRUE(found_exe);

  id_vector identifier1(make_vector());
  id_vector identifier2(make_vector());
  EXPECT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[i], true, i,
                                                 identifier1));
  FileID fileid(exe_name);
  EXPECT_TRUE(fileid.ElfFileIdentifier(identifier2));

  string identifier_string1 =
      FileID::ConvertIdentifierToUUIDString(identifier1);
  string identifier_string2 =
      FileID::ConvertIdentifierToUUIDString(identifier2);
  EXPECT_EQ(identifier_string1, identifier_string2);
}

/* Get back to normal behavior of TEST*() macros wrt TestBody. */
#undef TestBody

TEST(LinuxPtraceDumperTest, VerifyStackReadWithMultipleThreads) {
  static const int kNumberOfThreadsInHelperProgram = 5;

  pid_t child_pid = SetupChildProcess(kNumberOfThreadsInHelperProgram);
  ASSERT_NE(child_pid, -1);

  // Children are ready now.
  LinuxPtraceDumper dumper(child_pid);
  ASSERT_TRUE(dumper.Init());
  EXPECT_EQ((size_t)kNumberOfThreadsInHelperProgram, dumper.threads().size());
  EXPECT_TRUE(dumper.ThreadsSuspend());

  ThreadInfo one_thread;
  for (size_t i = 0; i < dumper.threads().size(); ++i) {
    EXPECT_TRUE(dumper.GetThreadInfoByIndex(i, &one_thread));
    const void* stack;
    size_t stack_len;
    EXPECT_TRUE(dumper.GetStackInfo(&stack, &stack_len,
        one_thread.stack_pointer));
    // In the helper program, we stored a pointer to the thread id in a
    // specific register. Check that we can recover its value.
#if defined(__ARM_EABI__)
    pid_t* process_tid_location = (pid_t*)(one_thread.regs.uregs[3]);
#elif defined(__aarch64__)
    pid_t* process_tid_location = (pid_t*)(one_thread.regs.regs[3]);
#elif defined(__i386)
    pid_t* process_tid_location = (pid_t*)(one_thread.regs.ecx);
#elif defined(__x86_64)
    pid_t* process_tid_location = (pid_t*)(one_thread.regs.rcx);
#elif defined(__mips__)
    pid_t* process_tid_location =
        reinterpret_cast<pid_t*>(one_thread.mcontext.gregs[1]);
#else
#error This test has not been ported to this platform.
#endif
    pid_t one_thread_id;
    dumper.CopyFromProcess(&one_thread_id,
                           dumper.threads()[i],
                           process_tid_location,
                           4);
    EXPECT_EQ(dumper.threads()[i], one_thread_id);
  }
  EXPECT_TRUE(dumper.ThreadsResume());
  kill(child_pid, SIGKILL);

  // Reap child
  int status;
  ASSERT_NE(-1, HANDLE_EINTR(waitpid(child_pid, &status, 0)));
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(SIGKILL, WTERMSIG(status));
}

TEST_F(LinuxPtraceDumperTest, SanitizeStackCopy) {
  static const int kNumberOfThreadsInHelperProgram = 1;

  pid_t child_pid = SetupChildProcess(kNumberOfThreadsInHelperProgram);
  ASSERT_NE(child_pid, -1);

  LinuxPtraceDumper dumper(child_pid);
  ASSERT_TRUE(dumper.Init());
  EXPECT_TRUE(dumper.ThreadsSuspend());

  ThreadInfo thread_info;
  EXPECT_TRUE(dumper.GetThreadInfoByIndex(0, &thread_info));

  const uintptr_t defaced =
#if defined(__LP64__)
      0x0defaced0defaced;
#else
      0x0defaced;
#endif

  uintptr_t simulated_stack[2];

  // Pointers into the stack shouldn't be sanitized.
  memset(simulated_stack, 0xff, sizeof(simulated_stack));
  simulated_stack[1] = thread_info.stack_pointer;
  dumper.SanitizeStackCopy(reinterpret_cast<uint8_t*>(&simulated_stack),
                           sizeof(simulated_stack), thread_info.stack_pointer,
                           sizeof(uintptr_t));
  ASSERT_NE(simulated_stack[1], defaced);

  // Memory prior to the stack pointer should be cleared.
  ASSERT_EQ(simulated_stack[0], 0u);

  // Small integers should not be sanitized.
  for (int i = -4096; i <= 4096; ++i) {
    memset(simulated_stack, 0, sizeof(simulated_stack));
    simulated_stack[0] = static_cast<uintptr_t>(i);
    dumper.SanitizeStackCopy(reinterpret_cast<uint8_t*>(&simulated_stack),
                             sizeof(simulated_stack), thread_info.stack_pointer,
                             0u);
    ASSERT_NE(simulated_stack[0], defaced);
  }

  // The instruction pointer definitely should point into an executable mapping.
  const MappingInfo* mapping_info = dumper.FindMappingNoBias(
      reinterpret_cast<uintptr_t>(thread_info.GetInstructionPointer()));
  ASSERT_NE(mapping_info, nullptr);
  ASSERT_TRUE(mapping_info->exec);

  // Pointers to code shouldn't be sanitized.
  memset(simulated_stack, 0, sizeof(simulated_stack));
  simulated_stack[1] = thread_info.GetInstructionPointer();
  dumper.SanitizeStackCopy(reinterpret_cast<uint8_t*>(&simulated_stack),
                           sizeof(simulated_stack), thread_info.stack_pointer,
                           0u);
  ASSERT_NE(simulated_stack[0], defaced);

  // String fragments should be sanitized.
  memcpy(simulated_stack, "abcdefghijklmnop", sizeof(simulated_stack));
  dumper.SanitizeStackCopy(reinterpret_cast<uint8_t*>(&simulated_stack),
                           sizeof(simulated_stack), thread_info.stack_pointer,
                           0u);
  ASSERT_EQ(simulated_stack[0], defaced);
  ASSERT_EQ(simulated_stack[1], defaced);

  // Heap pointers should be sanititzed.
#if defined(__ARM_EABI__)
  uintptr_t heap_addr = thread_info.regs.uregs[3];
#elif defined(__aarch64__)
  uintptr_t heap_addr = thread_info.regs.regs[3];
#elif defined(__i386)
  uintptr_t heap_addr = thread_info.regs.ecx;
#elif defined(__x86_64)
  uintptr_t heap_addr = thread_info.regs.rcx;
#elif defined(__mips__)
  uintptr_t heap_addr = thread_info.mcontext.gregs[1];
#else
#error This test has not been ported to this platform.
#endif
  memset(simulated_stack, 0, sizeof(simulated_stack));
  simulated_stack[0] = heap_addr;
  dumper.SanitizeStackCopy(reinterpret_cast<uint8_t*>(&simulated_stack),
                           sizeof(simulated_stack), thread_info.stack_pointer,
                           0u);
  ASSERT_EQ(simulated_stack[0], defaced);

  EXPECT_TRUE(dumper.ThreadsResume());
  kill(child_pid, SIGKILL);

  // Reap child.
  int status;
  ASSERT_NE(-1, HANDLE_EINTR(waitpid(child_pid, &status, 0)));
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(SIGKILL, WTERMSIG(status));
}
