// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "snapshot/linux/process_reader_linux.h"

#include <dlfcn.h>
#include <elf.h>
#include <errno.h>
#include <link.h>
#include <pthread.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <unistd.h>

#include <map>
#include <memory>
#include <string>
#include <utility>

#include "base/cxx17_backports.h"
#include "base/format_macros.h"
#include "base/memory/free_deleter.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "snapshot/linux/test_modules.h"
#include "test/errors.h"
#include "test/linux/fake_ptrace_connection.h"
#include "test/linux/get_tls.h"
#include "test/multiprocess.h"
#include "test/scoped_module_handle.h"
#include "test/test_paths.h"
#include "util/file/file_io.h"
#include "util/file/file_writer.h"
#include "util/file/filesystem.h"
#include "util/linux/direct_ptrace_connection.h"
#include "util/misc/address_sanitizer.h"
#include "util/misc/from_pointer_cast.h"
#include "util/misc/memory_sanitizer.h"
#include "util/synchronization/semaphore.h"

#if defined(OS_ANDROID)
#include <android/api-level.h>
#include <android/set_abort_message.h>
#include "dlfcn_internal.h"

// Normally this comes from set_abort_message.h, but only at API level 21.
extern "C" void android_set_abort_message(const char* msg)
    __attribute__((weak));
#endif

namespace crashpad {
namespace test {
namespace {

pid_t gettid() {
  return syscall(SYS_gettid);
}

TEST(ProcessReaderLinux, SelfBasic) {
  FakePtraceConnection connection;
  connection.Initialize(getpid());

  ProcessReaderLinux process_reader;
  ASSERT_TRUE(process_reader.Initialize(&connection));

#if defined(ARCH_CPU_64_BITS)
  EXPECT_TRUE(process_reader.Is64Bit());
#else
  EXPECT_FALSE(process_reader.Is64Bit());
#endif

  EXPECT_EQ(process_reader.ProcessID(), getpid());
  EXPECT_EQ(process_reader.ParentProcessID(), getppid());

  static constexpr char kTestMemory[] = "Some test memory";
  char buffer[base::size(kTestMemory)];
  ASSERT_TRUE(process_reader.Memory()->Read(
      reinterpret_cast<LinuxVMAddress>(kTestMemory),
      sizeof(kTestMemory),
      &buffer));
  EXPECT_STREQ(kTestMemory, buffer);

  EXPECT_EQ("", process_reader.AbortMessage());
}

constexpr char kTestMemory[] = "Read me from another process";

class BasicChildTest : public Multiprocess {
 public:
  BasicChildTest() : Multiprocess() {}

  BasicChildTest(const BasicChildTest&) = delete;
  BasicChildTest& operator=(const BasicChildTest&) = delete;

  ~BasicChildTest() {}

 private:
  void MultiprocessParent() override {
    DirectPtraceConnection connection;
    ASSERT_TRUE(connection.Initialize(ChildPID()));

    ProcessReaderLinux process_reader;
    ASSERT_TRUE(process_reader.Initialize(&connection));

#if !defined(ARCH_CPU_64_BITS)
    EXPECT_FALSE(process_reader.Is64Bit());
#else
    EXPECT_TRUE(process_reader.Is64Bit());
#endif

    EXPECT_EQ(process_reader.ParentProcessID(), getpid());
    EXPECT_EQ(process_reader.ProcessID(), ChildPID());

    std::string read_string;
    ASSERT_TRUE(process_reader.Memory()->ReadCString(
        reinterpret_cast<LinuxVMAddress>(kTestMemory), &read_string));
    EXPECT_EQ(read_string, kTestMemory);
  }

  void MultiprocessChild() override { CheckedReadFileAtEOF(ReadPipeHandle()); }
};

TEST(ProcessReaderLinux, ChildBasic) {
  BasicChildTest test;
  test.Run();
}

class TestThreadPool {
 public:
  struct ThreadExpectation {
    LinuxVMAddress tls = 0;
    LinuxVMAddress stack_address = 0;
    LinuxVMSize max_stack_size = 0;
    int sched_policy = 0;
    int static_priority = 0;
    int nice_value = 0;
  };

  TestThreadPool() : threads_() {}

  TestThreadPool(const TestThreadPool&) = delete;
  TestThreadPool& operator=(const TestThreadPool&) = delete;

  ~TestThreadPool() {
    for (const auto& thread : threads_) {
      thread->exit_semaphore.Signal();
    }

    for (const auto& thread : threads_) {
      EXPECT_EQ(pthread_join(thread->pthread, nullptr), 0)
          << ErrnoMessage("pthread_join");
    }
  }

  void StartThreads(size_t thread_count, size_t stack_size = 0) {
    for (size_t thread_index = 0; thread_index < thread_count; ++thread_index) {
      threads_.push_back(std::make_unique<Thread>());
      Thread* thread = threads_.back().get();

      pthread_attr_t attr;
      ASSERT_EQ(pthread_attr_init(&attr), 0)
          << ErrnoMessage("pthread_attr_init");

      if (stack_size > 0) {
        void* stack_ptr;
        errno = posix_memalign(&stack_ptr, getpagesize(), stack_size);
        ASSERT_EQ(errno, 0) << ErrnoMessage("posix_memalign");

        thread->stack.reset(reinterpret_cast<char*>(stack_ptr));

        ASSERT_EQ(pthread_attr_setstack(&attr, thread->stack.get(), stack_size),
                  0)
            << ErrnoMessage("pthread_attr_setstack");
        thread->expectation.max_stack_size = stack_size;
      }

      ASSERT_EQ(pthread_attr_setschedpolicy(&attr, SCHED_OTHER), 0)
          << ErrnoMessage("pthread_attr_setschedpolicy");
      thread->expectation.sched_policy = SCHED_OTHER;

      sched_param param;
      param.sched_priority = 0;
      ASSERT_EQ(pthread_attr_setschedparam(&attr, &param), 0)
          << ErrnoMessage("pthread_attr_setschedparam");
      thread->expectation.static_priority = 0;

      thread->expectation.nice_value = thread_index % 20;

      ASSERT_EQ(pthread_create(&thread->pthread, &attr, ThreadMain, thread), 0)
          << ErrnoMessage("pthread_create");
    }

    for (const auto& thread : threads_) {
      thread->ready_semaphore.Wait();
    }
  }

  pid_t GetThreadExpectation(size_t thread_index,
                             ThreadExpectation* expectation) {
    CHECK_LT(thread_index, threads_.size());

    const Thread* thread = threads_[thread_index].get();
    *expectation = thread->expectation;
    return thread->tid;
  }

 private:
  struct Thread {
    Thread()
        : pthread(),
          expectation(),
          ready_semaphore(0),
          exit_semaphore(0),
          tid(-1) {}
    ~Thread() {}

    pthread_t pthread;
    ThreadExpectation expectation;
    std::unique_ptr<char[], base::FreeDeleter> stack;
    Semaphore ready_semaphore;
    Semaphore exit_semaphore;
    pid_t tid;
  };

  static void* ThreadMain(void* argument) {
    Thread* thread = static_cast<Thread*>(argument);

    CHECK_EQ(setpriority(PRIO_PROCESS, 0, thread->expectation.nice_value), 0)
        << ErrnoMessage("setpriority");

    thread->expectation.tls = GetTLS();
    thread->expectation.stack_address =
        reinterpret_cast<LinuxVMAddress>(&thread);
    thread->tid = gettid();

    thread->ready_semaphore.Signal();
    thread->exit_semaphore.Wait();

    CHECK_EQ(pthread_self(), thread->pthread);

    return nullptr;
  }

  std::vector<std::unique_ptr<Thread>> threads_;
};

using ThreadMap = std::map<pid_t, TestThreadPool::ThreadExpectation>;

void ExpectThreads(const ThreadMap& thread_map,
                   const std::vector<ProcessReaderLinux::Thread>& threads,
                   PtraceConnection* connection) {
  ASSERT_EQ(threads.size(), thread_map.size());

  MemoryMap memory_map;
  ASSERT_TRUE(memory_map.Initialize(connection));

  for (const auto& thread : threads) {
    SCOPED_TRACE(
        base::StringPrintf("Thread id %d, tls 0x%" PRIx64
                           ", stack addr 0x%" PRIx64 ", stack size 0x%" PRIx64,
                           thread.tid,
                           thread.thread_info.thread_specific_data_address,
                           thread.stack_region_address,
                           thread.stack_region_size));

    const auto& iterator = thread_map.find(thread.tid);
    ASSERT_NE(iterator, thread_map.end());

    EXPECT_EQ(thread.thread_info.thread_specific_data_address,
              iterator->second.tls);

    ASSERT_TRUE(memory_map.FindMapping(thread.stack_region_address));
    ASSERT_TRUE(memory_map.FindMapping(thread.stack_region_address +
                                       thread.stack_region_size - 1));

#if !defined(ADDRESS_SANITIZER)
    // AddressSanitizer causes stack variables to be stored separately from the
    // call stack.
    EXPECT_LE(thread.stack_region_address, iterator->second.stack_address);
    EXPECT_GE(thread.stack_region_address + thread.stack_region_size,
              iterator->second.stack_address);
#endif  // !defined(ADDRESS_SANITIZER)

    if (iterator->second.max_stack_size) {
      EXPECT_LT(thread.stack_region_size, iterator->second.max_stack_size);
    }

    EXPECT_EQ(thread.sched_policy, iterator->second.sched_policy);
    EXPECT_EQ(thread.static_priority, iterator->second.static_priority);
    EXPECT_EQ(thread.nice_value, iterator->second.nice_value);
  }
}

class ChildThreadTest : public Multiprocess {
 public:
  ChildThreadTest(size_t stack_size = 0)
      : Multiprocess(), stack_size_(stack_size) {}

  ChildThreadTest(const ChildThreadTest&) = delete;
  ChildThreadTest& operator=(const ChildThreadTest&) = delete;

  ~ChildThreadTest() {}

 private:
  void MultiprocessParent() override {
    ThreadMap thread_map;
    for (size_t thread_index = 0; thread_index < kThreadCount + 1;
         ++thread_index) {
      pid_t tid;
      TestThreadPool::ThreadExpectation expectation;

      CheckedReadFileExactly(ReadPipeHandle(), &tid, sizeof(tid));
      CheckedReadFileExactly(
          ReadPipeHandle(), &expectation, sizeof(expectation));
      thread_map[tid] = expectation;
    }

    DirectPtraceConnection connection;
    ASSERT_TRUE(connection.Initialize(ChildPID()));

    ProcessReaderLinux process_reader;
    ASSERT_TRUE(process_reader.Initialize(&connection));
    const std::vector<ProcessReaderLinux::Thread>& threads =
        process_reader.Threads();
    ExpectThreads(thread_map, threads, &connection);
  }

  void MultiprocessChild() override {
    TestThreadPool thread_pool;
    thread_pool.StartThreads(kThreadCount, stack_size_);

    TestThreadPool::ThreadExpectation expectation;
#if defined(MEMORY_SANITIZER)
    // memset() + re-initialization is required to zero padding bytes for MSan.
    memset(&expectation, 0, sizeof(expectation));
#endif  // defined(MEMORY_SANITIZER)
    expectation = {};
    expectation.tls = GetTLS();
    expectation.stack_address = reinterpret_cast<LinuxVMAddress>(&thread_pool);

    int res = sched_getscheduler(0);
    ASSERT_GE(res, 0) << ErrnoMessage("sched_getscheduler");
    expectation.sched_policy = res;

    sched_param param;
    ASSERT_EQ(sched_getparam(0, &param), 0) << ErrnoMessage("sched_getparam");
    expectation.static_priority = param.sched_priority;

    errno = 0;
    res = getpriority(PRIO_PROCESS, 0);
    ASSERT_FALSE(res == -1 && errno) << ErrnoMessage("getpriority");
    expectation.nice_value = res;

    pid_t tid = gettid();

    CheckedWriteFile(WritePipeHandle(), &tid, sizeof(tid));
    CheckedWriteFile(WritePipeHandle(), &expectation, sizeof(expectation));

    for (size_t thread_index = 0; thread_index < kThreadCount; ++thread_index) {
      tid = thread_pool.GetThreadExpectation(thread_index, &expectation);
      CheckedWriteFile(WritePipeHandle(), &tid, sizeof(tid));
      CheckedWriteFile(WritePipeHandle(), &expectation, sizeof(expectation));
    }

    CheckedReadFileAtEOF(ReadPipeHandle());
  }

  static constexpr size_t kThreadCount = 3;
  const size_t stack_size_;
};

TEST(ProcessReaderLinux, ChildWithThreads) {
  ChildThreadTest test;
  test.Run();
}

TEST(ProcessReaderLinux, ChildThreadsWithSmallUserStacks) {
  ChildThreadTest test(PTHREAD_STACK_MIN);
  test.Run();
}

// Tests a thread with a stack that spans multiple mappings.
class ChildWithSplitStackTest : public Multiprocess {
 public:
  ChildWithSplitStackTest() : Multiprocess(), page_size_(getpagesize()) {}

  ChildWithSplitStackTest(const ChildWithSplitStackTest&) = delete;
  ChildWithSplitStackTest& operator=(const ChildWithSplitStackTest&) = delete;

  ~ChildWithSplitStackTest() {}

 private:
  void MultiprocessParent() override {
    LinuxVMAddress stack_addr1;
    LinuxVMAddress stack_addr2;
    LinuxVMAddress stack_addr3;

    CheckedReadFileExactly(ReadPipeHandle(), &stack_addr1, sizeof(stack_addr1));
    CheckedReadFileExactly(ReadPipeHandle(), &stack_addr2, sizeof(stack_addr2));
    CheckedReadFileExactly(ReadPipeHandle(), &stack_addr3, sizeof(stack_addr3));

    DirectPtraceConnection connection;
    ASSERT_TRUE(connection.Initialize(ChildPID()));

    ProcessReaderLinux process_reader;
    ASSERT_TRUE(process_reader.Initialize(&connection));

    const std::vector<ProcessReaderLinux::Thread>& threads =
        process_reader.Threads();
    ASSERT_EQ(threads.size(), 1u);

    LinuxVMAddress thread_stack_start = threads[0].stack_region_address;
    EXPECT_LE(thread_stack_start, stack_addr1);
    EXPECT_LE(thread_stack_start, stack_addr2);
    EXPECT_LE(thread_stack_start, stack_addr3);

    LinuxVMAddress thread_stack_end =
        thread_stack_start + threads[0].stack_region_size;
    EXPECT_GE(thread_stack_end, stack_addr1);
    EXPECT_GE(thread_stack_end, stack_addr2);
    EXPECT_GE(thread_stack_end, stack_addr3);
  }

  void MultiprocessChild() override {
    const LinuxVMSize stack_size = page_size_ * 4;
    GrowStack(stack_size, reinterpret_cast<LinuxVMAddress>(&stack_size));
  }

  void GrowStack(LinuxVMSize stack_size, LinuxVMAddress bottom_of_stack) {
    char stack_contents[4096];
    auto stack_address = reinterpret_cast<LinuxVMAddress>(&stack_contents);

    if (bottom_of_stack - stack_address < stack_size) {
      GrowStack(stack_size, bottom_of_stack);
    } else {
      // Write-protect a page on our stack to split up the mapping
      LinuxVMAddress page_addr =
          stack_address - (stack_address % page_size_) + 2 * page_size_;
      ASSERT_EQ(
          mprotect(reinterpret_cast<void*>(page_addr), page_size_, PROT_READ),
          0)
          << ErrnoMessage("mprotect");

      CheckedWriteFile(
          WritePipeHandle(), &bottom_of_stack, sizeof(bottom_of_stack));
      CheckedWriteFile(WritePipeHandle(), &page_addr, sizeof(page_addr));
      CheckedWriteFile(
          WritePipeHandle(), &stack_address, sizeof(stack_address));

      // Wait for parent to read us
      CheckedReadFileAtEOF(ReadPipeHandle());

      ASSERT_EQ(mprotect(reinterpret_cast<void*>(page_addr),
                         page_size_,
                         PROT_READ | PROT_WRITE),
                0)
          << ErrnoMessage("mprotect");
    }
  }

  const size_t page_size_;
};

// AddressSanitizer with use-after-return detection causes stack variables to
// be allocated on the heap.
#if defined(ADDRESS_SANITIZER)
#define MAYBE_ChildWithSplitStack DISABLED_ChildWithSplitStack
#else
#define MAYBE_ChildWithSplitStack ChildWithSplitStack
#endif
TEST(ProcessReaderLinux, MAYBE_ChildWithSplitStack) {
  ChildWithSplitStackTest test;
  test.Run();
}

// Android doesn't provide dl_iterate_phdr on ARM until API 21.
#if !defined(OS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21
int ExpectFindModule(dl_phdr_info* info, size_t size, void* data) {
  SCOPED_TRACE(
      base::StringPrintf("module %s at 0x%" PRIx64 " phdrs 0x%" PRIx64,
                         info->dlpi_name,
                         LinuxVMAddress{info->dlpi_addr},
                         FromPointerCast<LinuxVMAddress>(info->dlpi_phdr)));
  auto modules =
      reinterpret_cast<const std::vector<ProcessReaderLinux::Module>*>(data);


#if defined(OS_ANDROID)
  // Prior to API 27, Bionic includes a null entry for /system/bin/linker.
  if (!info->dlpi_name) {
    EXPECT_EQ(info->dlpi_addr, 0u);
    EXPECT_EQ(info->dlpi_phnum, 0u);
    EXPECT_EQ(info->dlpi_phdr, nullptr);
    return 0;
  }
#endif

  // Bionic doesn't always set both of these addresses for the vdso and
  // /system/bin/linker, but it does always set one of them.
  VMAddress module_addr = info->dlpi_phdr
                              ? FromPointerCast<LinuxVMAddress>(info->dlpi_phdr)
                              : info->dlpi_addr;

  // TODO(jperaza): This can use a range map when one is available.
  bool found = false;
  for (const auto& module : *modules) {
    if (module.elf_reader && module_addr >= module.elf_reader->Address() &&
        module_addr <
            module.elf_reader->Address() + module.elf_reader->Size()) {
      found = true;
      break;
    }
  }
  EXPECT_TRUE(found);
  return 0;
}
#endif  // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21

void ExpectModulesFromSelf(
    const std::vector<ProcessReaderLinux::Module>& modules) {
  for (const auto& module : modules) {
    EXPECT_FALSE(module.name.empty());
    EXPECT_NE(module.type, ModuleSnapshot::kModuleTypeUnknown);
  }

// Android doesn't provide dl_iterate_phdr on ARM until API 21.
#if !defined(OS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21
  EXPECT_EQ(
      dl_iterate_phdr(
          ExpectFindModule,
          reinterpret_cast<void*>(
              const_cast<std::vector<ProcessReaderLinux::Module>*>(&modules))),
      0);
#endif  // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21
}

#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
void ExpectTestModule(ProcessReaderLinux* reader,
                      const std::string& module_name) {
  for (const auto& module : reader->Modules()) {
    if (module.name.find(module_name) != std::string::npos) {
      ASSERT_TRUE(module.elf_reader);

      VMAddress dynamic_addr;
      ASSERT_TRUE(module.elf_reader->GetDynamicArrayAddress(&dynamic_addr));

      auto dynamic_mapping = reader->GetMemoryMap()->FindMapping(dynamic_addr);
      auto mappings =
          reader->GetMemoryMap()->FindFilePossibleMmapStarts(*dynamic_mapping);
      EXPECT_EQ(mappings->Count(), 2u);
      return;
    }
  }
  ADD_FAILURE() << "Test module not found";
}
#endif  // !ADDRESS_SANITIZER && !MEMORY_SANITIZER

TEST(ProcessReaderLinux, SelfModules) {
#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
  const std::string module_name = "test_module.so";
  const std::string module_soname = "test_module_soname";
  ScopedModuleHandle empty_test_module(
      LoadTestModule(module_name, module_soname));
  ASSERT_TRUE(empty_test_module.valid());
#endif  // !ADDRESS_SANITIZER && !MEMORY_SANITIZER

  FakePtraceConnection connection;
  connection.Initialize(getpid());

  ProcessReaderLinux process_reader;
  ASSERT_TRUE(process_reader.Initialize(&connection));

  ExpectModulesFromSelf(process_reader.Modules());
#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
  ExpectTestModule(&process_reader, module_soname);
#endif  // !ADDRESS_SANITIZER && !MEMORY_SANITIZER
}

class ChildModuleTest : public Multiprocess {
 public:
  ChildModuleTest() : Multiprocess(), module_soname_("test_module_soname") {}

  ChildModuleTest(const ChildModuleTest&) = delete;
  ChildModuleTest& operator=(const ChildModuleTest&) = delete;

  ~ChildModuleTest() = default;

 private:
  void MultiprocessParent() override {
    char c;
    ASSERT_TRUE(LoggingReadFileExactly(ReadPipeHandle(), &c, sizeof(c)));

    DirectPtraceConnection connection;
    ASSERT_TRUE(connection.Initialize(ChildPID()));

    ProcessReaderLinux process_reader;
    ASSERT_TRUE(process_reader.Initialize(&connection));

    ExpectModulesFromSelf(process_reader.Modules());
#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
    ExpectTestModule(&process_reader, module_soname_);
#endif  // !ADDRESS_SANITIZER && !MEMORY_SANITIZER
  }

  void MultiprocessChild() override {
#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
    ScopedModuleHandle empty_test_module(
        LoadTestModule("test_module.so", module_soname_));
    ASSERT_TRUE(empty_test_module.valid());
#endif  // !ADDRESS_SANITIZER && !MEMORY_SANITIZER

    char c = 0;
    ASSERT_TRUE(LoggingWriteFile(WritePipeHandle(), &c, sizeof(c)));

    CheckedReadFileAtEOF(ReadPipeHandle());
  }

  const std::string module_soname_;
};

TEST(ProcessReaderLinux, ChildModules) {
  ChildModuleTest test;
  test.Run();
}

#if defined(OS_ANDROID)
const char kTestAbortMessage[] = "test abort message";

TEST(ProcessReaderLinux, AbortMessage) {
  // This test requires Q. The API level on Q devices will be 28 until the API
  // is finalized, so we can't check API level yet. For now, test for the
  // presence of a libc symbol which was introduced in Q.
  if (!crashpad::internal::Dlsym(RTLD_DEFAULT,
                                 "android_fdsan_close_with_tag")) {
    GTEST_SKIP();
  }

  android_set_abort_message(kTestAbortMessage);

  FakePtraceConnection connection;
  connection.Initialize(getpid());

  ProcessReaderLinux process_reader;
  ASSERT_TRUE(process_reader.Initialize(&connection));

  EXPECT_EQ(kTestAbortMessage, process_reader.AbortMessage());
}
#endif

}  // namespace
}  // namespace test
}  // namespace crashpad
