// Copyright 2023 The Fuchsia 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 "src/starnix/tests/syscalls/cpp/task_test.h"

#include <fcntl.h>
#include <grp.h>
#include <limits.h>
#include <sched.h>
#include <strings.h>
#include <sys/fsuid.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/select.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <cerrno>
#include <cstdint>
#include <filesystem>
#include <thread>

#include <fbl/algorithm.h>
#include <gtest/gtest.h>
#include <linux/capability.h>
#include <linux/sched.h>

#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/fxl/strings/split_string.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/starnix/tests/syscalls/cpp/capabilities_helper.h"
#include "src/starnix/tests/syscalls/cpp/syscall_matchers.h"
#include "src/starnix/tests/syscalls/cpp/test_helper.h"

namespace {

#define MAX_PAGE_ALIGNMENT (1 << 21)

// Unless the split between the data and bss sections happens to be page-aligned, initial part
// of the bss section will be in the same page as the last part of the data section.
// By aligning g_global_variable_bss to a value bigger than the page size, we prevent it from
// ending up in this shared page
alignas(MAX_PAGE_ALIGNMENT) volatile int g_global_variable_bss = 0;

volatile size_t g_global_variable_data = 15;
volatile size_t g_fork_doesnt_drop_writes = 0;

// As of this writing, our sysroot's syscall.h lacks the SYS_clone3 definition.
#ifndef SYS_clone3
#if defined(__aarch64__) || defined(__x86_64__) || defined(__riscv)
#define SYS_clone3 435
#else
#error SYS_clone3 needs a definition for this architecture.
#endif
#endif

constexpr int kChildExpectedExitCode = 21;
constexpr int kChildErrorExitCode = kChildExpectedExitCode + 1;

constexpr uid_t kUser1Uid = 65533;
constexpr gid_t kUser1Gid = 65534;

bool change_ids(uid_t user, gid_t group) {
  return (setresgid(group, group, group) == 0) && (setresuid(user, user, user) == 0);
}

void WaitForReadFd(int fd) {
  fd_set read_fds;
  FD_ZERO(&read_fds);
  FD_SET(fd, &read_fds);

  SAFE_SYSCALL(TEMP_FAILURE_RETRY(select(fd + 1, &read_fds, nullptr, nullptr, nullptr)));
  EXPECT_TRUE(FD_ISSET(fd, &read_fds));
}

pid_t ForkUsingClone3(const clone_args* cl_args, size_t size) {
  return static_cast<pid_t>(syscall(SYS_clone3, cl_args, size));
}

// calls clone3 and executes a function, calling exit with its return value.
pid_t DoClone3(const clone_args* cl_args, size_t size, int (*func)(void*), void* param) {
  pid_t pid;
  // clone3 lets you specify a new stack, but not which function to run.
  // This means that after the clone3 syscall, the child will be running on a
  // new stack, not being able to access any local variables from before the
  // clone.
  //
  // We have to manually call into the new function in assembly, being careful
  // to not refer to any variables from the stack.
#if defined(__aarch64__)
  __asm__ volatile(
      "mov x0, %[cl_args]\n"
      "mov x1, %[size]\n"
      "mov w8, %[clone3]\n"
      "svc #0\n"
      "cbnz x0, 1f\n"
      "mov x0, %[param]\n"
      "blr %[func]\n"
      "mov w8, %[exit]\n"
      "svc #0\n"
      "brk #1\n"
      "1:\n"
      "mov %w[pid], w0\n"
      : [pid] "=r"(pid)
      : [cl_args] "r"(cl_args), "m"(*cl_args), [size] "r"(size), [func] "r"(func),
        [param] "r"(param), [clone3] "i"(SYS_clone3), [exit] "i"(SYS_exit)
      : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
        "x14", "x15", "x16", "x17", "cc", "memory");
#elif defined(__arm__)
  __asm__ volatile(
      "mov r0, %[cl_args]\n"
      "mov r1, %[size]\n"
      "mov r7, %[clone3]\n"
      "svc #0\n"
      "cmp r0, #0\n"
      "bne 1f\n"
      "mov r0, %[param]\n"
      "blx %[func]\n"
      "mov r7, %[exit]\n"
      "svc #0\n"
      "bkpt\n"
      "1:\n"
      "mov %[pid], r0\n"
      : [pid] "=r"(pid)
      : [cl_args] "r"(cl_args), "m"(*cl_args), [size] "r"(size), [func] "r"(func),
        [param] "r"(param), [clone3] "i"(SYS_clone3), [exit] "i"(SYS_exit)
      : "r0", "r1", "r2", "r3", "r7", "r12", "lr", "cc", "memory");
#elif defined(__x86_64__)
  __asm__ volatile(
      "syscall\n"
      "test %%rax, %%rax\n"
      "jnz 1f\n"
      "movq %[param], %%rdi\n"
      "callq *%[func]\n"
      "movl %%eax, %%edi\n"
      "movl %[exit], %%eax\n"
      "syscall\n"
      "ud2\n"
      "1:\n"
      "movl %%eax, %[pid]\n"
      : [pid] "=g"(pid)
      : "D"(cl_args), "m"(*cl_args), "S"(size),
        "a"(SYS_clone3), [func] "r"(func), [param] "r"(param), [exit] "i"(SYS_exit)
      : "rcx", "rdx", "r8", "r9", "r10", "r11", "cc", "memory");
#elif defined(__riscv)
  __asm__ volatile(
      "mv   a0, %[cl_args]\n"
      "mv   a1, %[size]\n"
      "li   a7, %[sys_clone3]\n"
      "ecall\n"
      "bnez a0, 1f\n"
      "mv   a0, %[param]\n"
      "jalr %[func]\n"
      "li   a7, %[sys_exit]\n"
      "ecall\n"
      "ebreak\n"
      "1:\n"
      "mv   %[pid], a0\n"
      : [pid] "=r"(pid)
      : [cl_args] "r"(cl_args), "m"(*cl_args), [size] "r"(size), [func] "r"(func),
        [param] "r"(param), [sys_clone3] "i"(SYS_clone3), [sys_exit] "i"(SYS_exit)
      : "ra", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "a0", "a1", "a2", "a3", "a4", "a5", "a6",
        "a7", "s1", "memory");
#else
#error clone3 needs a manual asm wrapper.
#endif

  if (pid < 0) {
    errno = -pid;
    pid = -1;
  }
  return pid;
}

int stack_test_func(void* a) {
  // Force a stack write by creating an asm block
  // that has an input that needs to come from memory.
  int pid = *reinterpret_cast<int*>(a);
  __asm__("" ::"m"(pid));

  if (getpid() != pid)
    return kChildErrorExitCode;

  return kChildExpectedExitCode;
}

int empty_func(void*) { return 0; }

void ReadStackStart(pid_t pid, uintptr_t* result) {
  std::string contents, path = fxl::StringPrintf("/proc/%ld/stat", static_cast<long>(pid));
  ASSERT_TRUE(files::ReadFileToString(path, &contents));

  auto parts = fxl::SplitString(contents, " ", fxl::kTrimWhitespace, fxl::kSplitWantAll);
  ASSERT_GE(parts.size(), 28U) << contents;
  ASSERT_TRUE(fxl::StringToNumberWithError(parts[27], result)) << parts[27];
}

void ReadStackSize(pid_t pid, uintptr_t* result) {
  std::string contents, path = fxl::StringPrintf("/proc/%ld/status", static_cast<long>(pid));
  ASSERT_TRUE(files::ReadFileToString(path, &contents));
  std::vector<std::string_view> lines =
      fxl::SplitString(contents, "\n", fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);

  bool vm_stk_found = false;
  for (auto line : lines) {
    auto key_and_value =
        fxl::SplitString(line, ": ", fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
    if (key_and_value.size() >= 2 && key_and_value[0] == "VmStk") {
      ASSERT_TRUE(fxl::StringToNumberWithError(key_and_value[1], result)) << line;
      vm_stk_found = true;
      break;
    }
  }

  ASSERT_TRUE(vm_stk_found) << contents;
}

void ReadProcPidFile(pid_t pid, const char* name, std::vector<uint8_t>* result) {
  std::string path = fxl::StringPrintf("/proc/%ld/%s", static_cast<long>(pid), name);
  ASSERT_TRUE(files::ReadFileToVector(path, result));
}

}  // namespace

// Creates a child process using the "clone3()" syscall and waits on it.
// The child uses a different stack than the parent.
TEST(Task, Clone3_ChangeStack) {
  struct clone_args ca;
  bzero(&ca, sizeof(ca));

  ca.flags = CLONE_PARENT_SETTID | CLONE_CHILD_SETTID;
  ca.exit_signal = SIGCHLD;  // Needed in order to wait on the child.

  // Ask for the child PID to be reported to both the parent and the child for validation.
  uint64_t child_pid_from_clone = 0;
  ca.parent_tid = reinterpret_cast<uint64_t>(&child_pid_from_clone);
  ca.child_tid = reinterpret_cast<uint64_t>(&child_pid_from_clone);

  constexpr size_t kStackSize = 0x5000;
  void* stack_addr = mmap(nullptr, kStackSize, PROT_WRITE | PROT_READ,
                          MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  ASSERT_NE(MAP_FAILED, stack_addr);

  ca.stack = reinterpret_cast<uint64_t>(stack_addr);
  ca.stack_size = kStackSize;

  auto child_pid = DoClone3(&ca, sizeof(ca), &stack_test_func, &child_pid_from_clone);
  ASSERT_NE(child_pid, -1);

  EXPECT_EQ(static_cast<pid_t>(child_pid_from_clone), child_pid);

  // Wait for the child to terminate and validate the exit code. Note that it returns a different
  // exit code above to indicate its state wasn't as expected.
  int wait_status = 0;
  pid_t wait_result = waitpid(child_pid, &wait_status, 0);
  EXPECT_EQ(wait_result, child_pid);

  EXPECT_TRUE(WIFEXITED(wait_status));
  auto exit_status = WEXITSTATUS(wait_status);
  EXPECT_NE(exit_status, kChildErrorExitCode) << "Child process reported state was unexpected.";
  EXPECT_EQ(exit_status, kChildExpectedExitCode) << "Wrong exit code from child process.";

  ASSERT_EQ(0, munmap(stack_addr, kStackSize));
}

// Forks a child process using the "clone3()" syscall and waits on it, validating some parameters.
TEST(Task, Clone3_Fork) {
  struct clone_args ca;
  bzero(&ca, sizeof(ca));

  ca.flags = CLONE_PARENT_SETTID | CLONE_CHILD_SETTID;
  ca.exit_signal = SIGCHLD;  // Needed in order to wait on the child.

  // Ask for the child PID to be reported to both the parent and the child for validation.
  uint64_t child_pid_from_clone = 0;
  ca.parent_tid = reinterpret_cast<uint64_t>(&child_pid_from_clone);
  ca.child_tid = reinterpret_cast<uint64_t>(&child_pid_from_clone);

  auto child_pid = ForkUsingClone3(&ca, sizeof(ca));
  ASSERT_NE(child_pid, -1);
  if (child_pid == 0) {
    // In child process. We'd like to EXPECT_EQ the pid but this is a child process and the gtest
    // failure won't get caught. Instead, return a different result code and the parent will notice
    // and issue an error about the state being unexpected.
    if (getpid() != static_cast<pid_t>(child_pid_from_clone))
      exit(kChildErrorExitCode);
    exit(kChildExpectedExitCode);
  } else {
    EXPECT_EQ(static_cast<pid_t>(child_pid_from_clone), child_pid);

    // Wait for the child to terminate and validate the exit code. Note that it returns a different
    // exit code above to indicate its state wasn't as expected.
    int wait_status = 0;
    pid_t wait_result = waitpid(child_pid, &wait_status, 0);
    EXPECT_EQ(wait_result, child_pid);

    EXPECT_TRUE(WIFEXITED(wait_status));
    auto exit_status = WEXITSTATUS(wait_status);
    EXPECT_NE(exit_status, kChildErrorExitCode) << "Child process reported state was unexpected.";
    EXPECT_EQ(exit_status, kChildExpectedExitCode) << "Wrong exit code from child process.";
  }
}

// Forks a child process using the "clone3()" syscall and requests a PID-FD for it.
TEST(Task, Clone3_PidFd) {
  struct clone_args ca;
  bzero(&ca, sizeof(ca));

  ca.flags = CLONE_PIDFD;
  ca.exit_signal = SIGCHLD;  // Needed in order to wait on the child.

  // Ask for a PID FD through which the child process can be observed.
  fbl::unique_fd pid_fd;
  ca.pidfd = reinterpret_cast<uint64_t>(pid_fd.reset_and_get_address());

  auto child_pid = ForkUsingClone3(&ca, sizeof(ca));
  ASSERT_NE(child_pid, -1) << strerror(errno);
  if (child_pid == 0) {
    exit(kChildExpectedExitCode);
  } else {
    EXPECT_TRUE(pid_fd.is_valid());

    // Wait for the child to terminate.
    int wait_status = 0;
    pid_t wait_result = waitpid(child_pid, &wait_status, 0);
    EXPECT_EQ(wait_result, child_pid) << strerror(errno);
  }
}

static int ClonePidFdFunctionExit(void*) { exit(kChildExpectedExitCode); }

// Forks a child process using the "clone()" syscall and requests a PID-FD for it.
TEST(Task, Clone_PidFd) {
  constexpr size_t kStackSize = 1024 * 16;
  void* stack_low = mmap(nullptr, kStackSize, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  ASSERT_NE(stack_low, MAP_FAILED);
  void* stack_high = static_cast<char*>(stack_low) + kStackSize;  // Pass in the top of the stack.

  fbl::unique_fd pid_fd;
  auto child_pid = clone(&ClonePidFdFunctionExit, stack_high, SIGCHLD | CLONE_PIDFD,
                         /*arg=*/nullptr, pid_fd.reset_and_get_address());
  ASSERT_NE(child_pid, -1) << strerror(errno);
  EXPECT_TRUE(pid_fd.is_valid());

  // Wait for the child to terminate.
  int wait_status = 0;
  pid_t wait_result = waitpid(child_pid, &wait_status, 0);
  EXPECT_EQ(wait_result, child_pid) << strerror(errno);
}

// Forks a child process using the "clone()" syscall and requests both PID-FD and parent TID.
TEST(Task, Clone_PidFdAndParentTid) {
  constexpr size_t kStackSize = 1024 * 16;
  void* stack_low = mmap(nullptr, kStackSize, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  ASSERT_NE(stack_low, MAP_FAILED);
  void* stack_high = static_cast<char*>(stack_low) + kStackSize;  // Pass in the top of the stack.

  uintptr_t out_arg{};
  auto child_pid =
      clone(&ClonePidFdFunctionExit, stack_high, SIGCHLD | CLONE_PIDFD | CLONE_PARENT_SETTID,
            /*arg=*/nullptr, &out_arg);
  EXPECT_EQ(child_pid, -1);
}

TEST(Task, Clone3_InvalidSize) {
  struct clone_args ca;
  bzero(&ca, sizeof(ca));

  // Pass a structure size smaller than the first supported version, it should report EINVAL.
  EXPECT_EQ(-1, DoClone3(&ca, CLONE_ARGS_SIZE_VER0 - 8, &empty_func, nullptr));
  EXPECT_EQ(EINVAL, errno);
}

static int CloneVForkFunctionSleepExit(void* param) {
  struct timespec wait{.tv_sec = 0, .tv_nsec = kCloneVforkSleepUS * 1000};
  nanosleep(&wait, nullptr);
  // Note: exit() is a stdlib function that exits the whole process which we don't want.
  // _exit just exits the current thread which is what matches clone().
  _exit(1);
  return 0;
}

// Tests a CLONE_VFORK and the cloned thread exits before calling execve. The clone() call should
// block until the thread exits.
TEST(Task, CloneVfork_exit) {
  constexpr size_t kStackSize = 1024 * 16;
  void* stack_low = mmap(nullptr, kStackSize, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  ASSERT_NE(stack_low, MAP_FAILED);
  void* stack_high = static_cast<char*>(stack_low) + kStackSize;  // Pass in the top of the stack.

  struct timeval begin;
  struct timezone tz;
  gettimeofday(&begin, &tz);

  // This uses the glibc "clone()" wrapper function which takes a function pointer.
  int result = clone(&CloneVForkFunctionSleepExit, stack_high, CLONE_VFORK, 0);
  ASSERT_NE(result, -1);

  struct timeval end;
  gettimeofday(&end, &tz);

  // The clone function should have been blocked for at least as long as the sleep was for.
  uint64_t elapsed_us = ((int64_t)end.tv_sec - (int64_t)begin.tv_sec) * 1000000ll +
                        ((int64_t)end.tv_usec - (int64_t)begin.tv_usec);
  EXPECT_GT(elapsed_us, kCloneVforkSleepUS);
}

// Invokes `brk()` syscall directly. The syscall returns the requested `new_break` on success,
// or the old break on failure. Setting `new_break` to null always fails, so can be used to
// retrieve the current break.
// Some tests invoke this directly so as to bypass the `brk()` wrapper provided by some libc
// implementations, that has different behaviour, matching the POSIX specification.
uintptr_t brk_syscall(uintptr_t new_break) { return syscall(SYS_brk, new_break); }

TEST(Task, BrkReturnsCurrentBreakOnFailure) {
  // Tests that the brk system call doesn't return an error, instead it returns
  // the current value of the program break.
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    const size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));

    // This should always fail, returning the program_break
    uintptr_t program_break = brk_syscall(UINTPTR_MAX);

    // Try to reserve something beyond the program break, aligned to page size.
    uintptr_t map_addr = (program_break & ~(page_size - 1)) + page_size;
    uintptr_t res =
        reinterpret_cast<uintptr_t>(mmap(reinterpret_cast<void*>(map_addr), page_size, PROT_NONE,
                                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0));
    ASSERT_EQ(res, map_addr);

    uintptr_t new_break = brk_syscall(map_addr + page_size);
    // brk should fail.
    EXPECT_EQ(new_break, program_break);

    _exit(testing::Test::HasFailure());
  });

  EXPECT_TRUE(helper.WaitForChildren());
}

TEST(Task, BrkShrinkAfterFork) {
  // Tests that a program can shrink their break after forking.
  const void* kSbrkError = reinterpret_cast<void*>(-1);
  test_helper::ForkHelper helper;

  constexpr int brk_increment = 0x4000;
  ASSERT_NE(kSbrkError, sbrk(brk_increment));
  void* old_brk = sbrk(0);
  ASSERT_NE(kSbrkError, old_brk);
  helper.RunInForkedProcess([&] {
    ASSERT_EQ(old_brk, sbrk(0));
    ASSERT_NE(kSbrkError, sbrk(-brk_increment));
  });

  // Make sure fork didn't change our current break.
  ASSERT_EQ(old_brk, sbrk(0));

  // Restore the old brk.
  ASSERT_NE(kSbrkError, sbrk(-brk_increment));
}

// Returns true if the `len` bytes at `ptr` all have value `value`.
static bool mem_contains(volatile char* ptr, size_t len, char value) {
  for (const auto* end = ptr + len; ptr != end; ++ptr) {
    if (*ptr != value)
      return false;
  }
  return true;
}

// Moves the program break to a page aligned address, and returns the old break address.
static uintptr_t set_brk_page_aligned() {
  size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));
  uintptr_t original_break = brk_syscall(0);
  uintptr_t aligned_break = (original_break + page_size) & ~(page_size - 1);
  if (brk_syscall(aligned_break) != aligned_break) {
    return 0;
  }
  return original_break;
}

// Verify that if the program break is reduced down to a page-aligned address, and then
// regrown, then all the pages, including the one pointed to by the page-aligned address,
// are zeroed.
TEST(Task, BrkIsZeroedAfterShrinkAndRegrow) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    const void* kSbrkError = reinterpret_cast<void*>(-1);

    ASSERT_NE(set_brk_page_aligned(), 0u);

    // Allocate space via `sbrk()`, and fill it with non-zero bytes.
    constexpr intptr_t kBreakIncrement = 0x4142;
    void* base_break = sbrk(kBreakIncrement);
    ASSERT_NE(base_break, kSbrkError) << "sbrk failed: " << std::strerror(errno);
    char* memory = static_cast<char*>(base_break);
    ASSERT_TRUE(mem_contains(memory, static_cast<size_t>(kBreakIncrement), 0));
    memset(memory, 'a', kBreakIncrement);
    ASSERT_FALSE(mem_contains(memory, static_cast<size_t>(kBreakIncrement), 0));

    // Shrink the `sbrk()` to free the pages, then re-allocate them.
    ASSERT_NE(sbrk(-kBreakIncrement), kSbrkError) << "sbrk failed: " << std::strerror(errno);
    ASSERT_NE(sbrk(kBreakIncrement), kSbrkError) << "sbrk failed: " << std::strerror(errno);

    // The re-allocated range should now be zeroed.
    EXPECT_TRUE(mem_contains(memory, static_cast<size_t>(kBreakIncrement), 0));

    _exit(testing::Test::HasFailure());
  });
}

// Verifies that overwriting the program break with private or shared mappings does not
// prevent the program break from being shrunk, and regrown.
TEST(Task, BrkShrinkUnmapsAnonMmap) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    ASSERT_NE(set_brk_page_aligned(), 0u);

    size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));

    // Allocate eight pages from the program break.
    uintptr_t program_break = brk_syscall(0);
    uintptr_t new_break = brk_syscall(program_break + (8 * page_size));
    ASSERT_EQ(new_break, program_break + (8 * page_size));

    // Anonymously map over second and third pages, with RW and read-only private pages.
    uintptr_t addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + page_size), page_size, PROT_WRITE | PROT_READ,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + page_size);
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (2 * page_size)), page_size, PROT_READ,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (2 * page_size));

    // Anonymously map over fifth and sixth pages, with RW and read-only shared pages.
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (4 * page_size)), page_size,
             PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (4 * page_size));
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (5 * page_size)), page_size, PROT_READ,
             MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (5 * page_size));

    // Shrink the program break back down.
    uintptr_t final_break = brk_syscall(program_break);
    EXPECT_EQ(final_break, program_break);

    // Validate that all eight pages are no longer available.
    for (size_t i = 0; i < 8; i++) {
      EXPECT_FALSE(test_helper::TryRead(program_break + (i * page_size)))
          << "page " << i + 1 << " is readable";
    }

    // Regrow and validate that all eight pages are then readable.
    new_break = brk_syscall(program_break + (8 * page_size));
    EXPECT_EQ(new_break, program_break + (8 * page_size));
    for (size_t i = 0; i < 8; i++) {
      EXPECT_TRUE(test_helper::TryRead(program_break + (i * page_size)))
          << "page " << i + 1 << " not readable";
    }

    _exit(testing::Test::HasFailure());
  });
}

// Verifies that the program break can be extended after `mmap()` has been used to overwrite
// preceding parts of the program break area, and that doing so does not alter those
// mappings.
TEST(Task, BrkGrowsAfterAnonMmap) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    ASSERT_NE(set_brk_page_aligned(), 0u);

    size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));

    // Allocate eight pages from the program break, and set them non-zero.
    uintptr_t program_break = brk_syscall(0);
    uintptr_t new_break = brk_syscall(program_break + (8 * page_size));
    ASSERT_EQ(new_break, program_break + (8 * page_size));

    char* break_memory = reinterpret_cast<char*>(program_break);
    memset(break_memory, 'a', 8 * page_size);
    ASSERT_TRUE(mem_contains(break_memory, 8 * page_size, 'a'));

    // Anonymously map over second and third pages, with RW and read-only private pages.
    uintptr_t addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + page_size), page_size, PROT_WRITE | PROT_READ,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + page_size);
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (2 * page_size)), page_size, PROT_READ,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (2 * page_size));

    // Anonymously map over fifth and sixth pages, with RW and read-only shared pages.
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (4 * page_size)), page_size,
             PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (4 * page_size));
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (5 * page_size)), page_size, PROT_READ,
             MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (5 * page_size));

    // Fill the writable `mmap()`ed pages with identifiable content.
    memset(break_memory + page_size, 'b', page_size);
    memset(break_memory + 4 * page_size, 'c', page_size);

    // Extend the program break by another eight pages.
    new_break = brk_syscall(program_break + (16 * page_size));
    ASSERT_EQ(new_break, program_break + (16 * page_size));

    // Everything preceding the old break should be preserved.
    EXPECT_TRUE(mem_contains(break_memory, page_size, 'a'));  // first of the old break pages
    EXPECT_TRUE(mem_contains(break_memory + page_size, page_size, 'b'));
    EXPECT_TRUE(mem_contains(break_memory + 4 * page_size, page_size, 'c'));
    EXPECT_TRUE(mem_contains(break_memory + 7 * page_size, page_size,
                             'a'));  // last of the old break pages.

    // The new break area will be zeroed.
    EXPECT_TRUE(mem_contains(break_memory + 8 * page_size, 8 * page_size, 0));

    _exit(testing::Test::HasFailure());
  });
}

// Verify that the program break will not grow over existing private mappings.
TEST(Task, BrkWillNotGrowOverPrivateAnonMmap) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    ASSERT_NE(set_brk_page_aligned(), 0u);

    size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));

    // Create anonymous mapped pages after the break.
    uintptr_t program_break = brk_syscall(0);

    // Anonymously map over second and third pages, with RW and read-only private pages.
    uintptr_t addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + page_size), page_size, PROT_WRITE | PROT_READ,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + page_size);
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (2 * page_size)), page_size, PROT_READ,
             MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (2 * page_size));

    // Attempt to grow the program break over the private mappings.
    // This should fail, causing the old program break position to remain current.
    uintptr_t new_break = brk_syscall(program_break + (8 * page_size));
    EXPECT_EQ(new_break, program_break);

    _exit(testing::Test::HasFailure());
  });
}

// Verify that the program break will not grow over existing private mappings.
TEST(Task, BrkWillNotGrowOverSharedAnonMmap) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    ASSERT_NE(set_brk_page_aligned(), 0u);

    size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));

    // Create shared mapped pages after the break.
    uintptr_t program_break = brk_syscall(0);

    // Anonymously map over second and fourth pages, with RW and read-only shared pages.
    uintptr_t addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (page_size)), page_size,
             PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + page_size);
    addr = reinterpret_cast<uintptr_t>(
        mmap(reinterpret_cast<void*>(program_break + (3 * page_size)), page_size, PROT_READ,
             MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
    ASSERT_EQ(addr, program_break + (3 * page_size));

    // Attempt to grow the program break over the shared mappings.
    // This should fail, causing the old program break position to remain current.
    uintptr_t new_break = brk_syscall(program_break + (8 * page_size));
    EXPECT_EQ(new_break, program_break);

    _exit(testing::Test::HasFailure());
  });
}

// Verify that the `brk()` syscall continues to function after pages within the
// program break have been explicitly unmapped by the caller.
TEST(Task, BrkCanBeUnmapped) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    ASSERT_NE(set_brk_page_aligned(), 0u);

    size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));

    // Allocate a page from the program break.
    uintptr_t program_break = brk_syscall(0);
    uintptr_t new_break = brk_syscall(program_break + page_size);

    // Unmap the last page we just added.
    ASSERT_TRUE(test_helper::TryRead(program_break));
    SAFE_SYSCALL(munmap(reinterpret_cast<void*>(program_break), page_size));
    EXPECT_FALSE(test_helper::TryRead(program_break));

    // The program break hasn't changed.
    uintptr_t break_after_unmap = brk_syscall(0);
    EXPECT_EQ(break_after_unmap, new_break);

    // The program break can still be extended.
    uintptr_t final_break = brk_syscall(new_break + page_size);
    EXPECT_EQ(final_break, new_break + page_size);

    // The final page of the break is readable, and the unmapped page is still not.
    EXPECT_TRUE(test_helper::TryRead(new_break));
    EXPECT_FALSE(test_helper::TryRead(program_break));

    // The break can be rewound over the unmapped region.
    EXPECT_EQ(brk_syscall(program_break), program_break);

    _exit(testing::Test::HasFailure());
  });

  EXPECT_TRUE(helper.WaitForChildren());
}

// Verify that the current program break address is treated as outside the break.
TEST(Task, BrkIsOutOfRange) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([] {
    // Set the program break to be page-aligned.
    ASSERT_NE(set_brk_page_aligned(), 0u);

    // The break address should refer to the first byte of the page after the break,
    // and therefore not be mapped.
    uintptr_t aligned_break = brk_syscall(0);
    EXPECT_FALSE(test_helper::TryRead(aligned_break));

    // Increasing the break by one byte effectively "allocates" the byte at the
    // aligned break address, causing that page to now be mapped.
    uintptr_t increased_break = aligned_break + 1;
    EXPECT_EQ(brk_syscall(increased_break), increased_break);
    EXPECT_TRUE(test_helper::TryRead(aligned_break));

    // Reducing the break by one byte "deallocates" the byte at the aligned
    // address, causing the page to be unmapped.
    EXPECT_EQ(brk_syscall(aligned_break), aligned_break);
    EXPECT_FALSE(test_helper::TryRead(aligned_break));

    _exit(testing::Test::HasFailure());
  });

  EXPECT_TRUE(helper.WaitForChildren());
}

TEST(Task, ChildCantModifyParent) {
  ASSERT_GT(MAX_PAGE_ALIGNMENT, getpagesize());

  test_helper::ForkHelper helper;

  g_global_variable_data = 1;
  g_global_variable_bss = 10;
  volatile int local_variable = 100;
  volatile int* heap_variable = new volatile int();
  *heap_variable = 1000;

  ASSERT_EQ(g_global_variable_data, 1u);
  ASSERT_EQ(g_global_variable_bss, 10);
  ASSERT_EQ(local_variable, 100);
  ASSERT_EQ(*heap_variable, 1000);

  helper.RunInForkedProcess([&] {
    g_global_variable_data = 2;
    g_global_variable_bss = 20;
    local_variable = 200;
    *heap_variable = 2000;
  });
  ASSERT_TRUE(helper.WaitForChildren());

  EXPECT_EQ(g_global_variable_data, 1u);
  EXPECT_EQ(g_global_variable_bss, 10);
  EXPECT_EQ(local_variable, 100);
  EXPECT_EQ(*heap_variable, 1000);
  delete heap_variable;
}

TEST(Task, ForkDoesntDropWrites) {
  // This tests creates a thread that keeps reading
  // and writing to a pager-backed memory region (the data section of this
  // binary).
  //
  // This is to test that during fork, writes to pager-backed vmos are not
  // dropped if we have concurrent processes writing to memory while the kernel
  // changes those mappings.
  std::atomic<bool> stop = false;
  std::atomic<bool> success = false;
  std::vector<pid_t> pids;

  std::thread writer([&stop, &success, &data = g_fork_doesnt_drop_writes]() {
    data = 0;
    size_t i = 0;
    success = false;
    while (!stop) {
      i++;
      data += 1;
      if (data != i) {
        return;
      }
    }
    success = true;
  });

  for (size_t i = 0; i < 1000; i++) {
    pid_t pid = fork();
    if (pid == 0) {
      _exit(0);
    }
    pids.push_back(pid);
  }

  stop = true;
  writer.join();
  EXPECT_TRUE(success.load());

  for (auto pid : pids) {
    int status;
    EXPECT_EQ(waitpid(pid, &status, 0), pid);
    EXPECT_TRUE(WIFEXITED(status));
    EXPECT_EQ(WEXITSTATUS(status), 0);
  }
}

TEST(Task, ParentCantModifyChild) {
  ASSERT_GT(MAX_PAGE_ALIGNMENT, getpagesize());

  test_helper::ForkHelper helper;

  g_global_variable_data = 1;
  g_global_variable_bss = 10;
  volatile int local_variable = 100;
  volatile int* heap_variable = new volatile int();
  *heap_variable = 1000;

  ASSERT_EQ(g_global_variable_data, 1u);
  ASSERT_EQ(g_global_variable_bss, 10);
  ASSERT_EQ(local_variable, 100);
  ASSERT_EQ(*heap_variable, 1000);

  test_helper::SignalMaskHelper signal_helper = test_helper::SignalMaskHelper();
  signal_helper.blockSignal(SIGUSR1);

  pid_t child_pid = helper.RunInForkedProcess([&] {
    signal_helper.waitForSignal(SIGUSR1);

    EXPECT_EQ(g_global_variable_data, 1u);
    EXPECT_EQ(g_global_variable_bss, 10);
    EXPECT_EQ(local_variable, 100);
    EXPECT_EQ(*heap_variable, 1000);
  });

  g_global_variable_data = 2;
  g_global_variable_bss = 20;
  local_variable = 200;
  *heap_variable = 2000;

  ASSERT_EQ(kill(child_pid, SIGUSR1), 0);

  ASSERT_TRUE(helper.WaitForChildren());
  signal_helper.restoreSigmask();

  delete heap_variable;
}

constexpr size_t kVecSize = 100;
constexpr size_t kPageLimit = 32;

TEST(Task, ExecveArgumentExceedsMaxArgStrlen) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([] {
    size_t arg_size = kPageLimit * sysconf(_SC_PAGESIZE);
    std::vector<char> arg(arg_size + 1, 'a');
    arg[arg_size] = '\0';
    char* argv[] = {arg.data(), nullptr};
    char* envp[] = {nullptr};
    EXPECT_NE(execve("/proc/self/exe", argv, envp), 0);
    EXPECT_EQ(errno, E2BIG);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ExecveArgvExceedsLimit) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([] {
    size_t arg_size = kPageLimit * sysconf(_SC_PAGESIZE);
    std::vector<char> arg(arg_size, 'a');
    arg[arg_size - 1] = '\0';
    char* argv[kVecSize];
    std::fill_n(argv, kVecSize - 1, arg.data());
    argv[kVecSize - 1] = nullptr;
    char* envp[] = {nullptr};
    EXPECT_NE(execve("/proc/self/exe", argv, envp), 0);
    EXPECT_EQ(errno, E2BIG);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ExecveArgvEnvExceedLimit) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([] {
    size_t arg_size = kPageLimit * sysconf(_SC_PAGESIZE);
    std::vector<char> string(arg_size, 'a');
    string[arg_size - 1] = '\0';
    char* argv[] = {string.data(), nullptr};
    char* envp[kVecSize];
    std::fill_n(envp, kVecSize - 1, string.data());
    envp[kVecSize - 1] = nullptr;
    EXPECT_NE(execve("/proc/self/exe", argv, envp), 0);
    EXPECT_EQ(errno, E2BIG);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ExecvePathnameTooLong) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([] {
    constexpr size_t path_size = PATH_MAX + 1;
    // We use '/' here because ////// (...) is a valid path:
    // More than two leading / should be considered as one,
    // So this path resolves to "/".
    //
    // Each path component is limited to NAME_MAX, so if we
    // use a different character we would need to add a delimiter
    // every NAME_MAX characters.
    std::vector<char> pathname(path_size, '/');
    pathname[path_size - 1] = '\0';

    char* argv[] = {nullptr};
    char* envp[] = {nullptr};

    EXPECT_NE(execve(pathname.data(), argv, envp), 0);
    EXPECT_EQ(errno, ENAMETOOLONG);
  });

  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ForkPreservesStackStart) {
  pid_t parent_pid = getpid();
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([parent_pid] {
    uintptr_t parent_stack_start, child_stack_start;
    ASSERT_NO_FATAL_FAILURE(ReadStackStart(parent_pid, &parent_stack_start));
    ASSERT_NO_FATAL_FAILURE(ReadStackStart(getpid(), &child_stack_start));
    EXPECT_EQ(parent_stack_start, child_stack_start);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ForkPreservesStackSize) {
  pid_t parent_pid = getpid();
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([parent_pid] {
    uintptr_t parent_stack_size, child_stack_size;
    ASSERT_NO_FATAL_FAILURE(ReadStackSize(parent_pid, &parent_stack_size));
    ASSERT_NO_FATAL_FAILURE(ReadStackSize(getpid(), &child_stack_size));
    EXPECT_EQ(parent_stack_size, child_stack_size);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ForkPreservesAux) {
  pid_t parent_pid = getpid();
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([parent_pid] {
    std::vector<uint8_t> parent_auxv, child_auxv;
    ASSERT_NO_FATAL_FAILURE(ReadProcPidFile(parent_pid, "auxv", &parent_auxv));
    ASSERT_NO_FATAL_FAILURE(ReadProcPidFile(getpid(), "auxv", &child_auxv));
    EXPECT_EQ(parent_auxv, child_auxv);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ForkPreservesCmdline) {
  pid_t parent_pid = getpid();
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([parent_pid] {
    std::vector<uint8_t> parent_cmdline, child_cmdline;
    ASSERT_NO_FATAL_FAILURE(ReadProcPidFile(parent_pid, "cmdline", &parent_cmdline));
    ASSERT_NO_FATAL_FAILURE(ReadProcPidFile(getpid(), "cmdline", &child_cmdline));
    EXPECT_EQ(parent_cmdline, child_cmdline);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, ForkPreservesEnviron) {
  pid_t parent_pid = getpid();
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([parent_pid] {
    std::vector<uint8_t> parent_environ, child_environ;
    ASSERT_NO_FATAL_FAILURE(ReadProcPidFile(parent_pid, "environ", &parent_environ));
    ASSERT_NO_FATAL_FAILURE(ReadProcPidFile(getpid(), "environ", &child_environ));
    EXPECT_EQ(parent_environ, child_environ);
  });
  ASSERT_TRUE(helper.WaitForChildren());
}

TEST(Task, KillESRCH) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([]() {
    pid_t pid = getpid();

    // A pid after fork is guaranteed to not collide with process group ids.
    EXPECT_THAT(kill(-pid, SIGCHLD), SyscallFailsWithErrno(ESRCH));
  });
}

TEST(Task, KillChildEPERM) {
  if (!test_helper::HasSysAdmin()) {
    GTEST_SKIP() << "test requires root privileges";
  }

  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([]() {
    test_helper::EventFdSem fd(0);

    pid_t child_pid = SAFE_SYSCALL(fork());
    if (child_pid == 0) {
      fd.Wait();
      _exit(EXIT_SUCCESS);
    }

    SAFE_SYSCALL(change_ids(kUser1Uid, kUser1Gid));

    EXPECT_THAT(kill(child_pid, SIGCHLD), SyscallFailsWithErrno(EPERM));
    fd.Notify(1);

    SAFE_SYSCALL(waitpid(child_pid, nullptr, 0));
  });
}

TEST(Task, KillZombie) {
  test_helper::ForkHelper helper;

  helper.RunInForkedProcess([]() {
    pid_t child_pid = SAFE_SYSCALL(fork());
    if (child_pid == 0) {
      _exit(EXIT_SUCCESS);
    }

    int pidfd = test_helper::PidFdOpen(child_pid, 0);
    WaitForReadFd(pidfd);
    close(pidfd);

    EXPECT_THAT(kill(child_pid, SIGCHLD), SyscallSucceeds());
    SAFE_SYSCALL(waitpid(child_pid, nullptr, 0));
  });
}

TEST(Task, KillZombieEPERM) {
  if (!test_helper::HasSysAdmin()) {
    GTEST_SKIP() << "test requires root privileges";
  }

  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([]() {
    pid_t child_pid = SAFE_SYSCALL(fork());
    if (child_pid == 0) {
      _exit(EXIT_SUCCESS);
    }

    int pidfd = test_helper::PidFdOpen(child_pid, 0);
    WaitForReadFd(pidfd);
    close(pidfd);

    SAFE_SYSCALL(change_ids(kUser1Uid, kUser1Gid));
    EXPECT_THAT(kill(child_pid, SIGCHLD), SyscallFailsWithErrno(EPERM));
    SAFE_SYSCALL(waitpid(child_pid, nullptr, 0));
  });
}

TEST(Task, KillParentEPERM) {
  if (!test_helper::HasSysAdmin()) {
    GTEST_SKIP() << "test requires root privileges";
  }

  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([]() {
    test_helper::EventFdSem fd(0);

    pid_t child_pid = SAFE_SYSCALL(fork());
    if (child_pid == 0) {
      pid_t parent_pid = getppid();
      SAFE_SYSCALL(change_ids(kUser1Uid, kUser1Gid));

      EXPECT_THAT(kill(parent_pid, SIGCHLD), SyscallFailsWithErrno(EPERM));
      SAFE_SYSCALL(fd.Notify(1));
      _exit(EXIT_SUCCESS);
    }

    fd.Wait();
    SAFE_SYSCALL(waitpid(child_pid, nullptr, 0));
  });
}

TEST(Task, CantReadLowAddresses) {
  if (!test_helper::IsStarnix()) {
    GTEST_SKIP();
  }

  const size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));
  constexpr uintptr_t kLowMemoryLimit = 16 * 1024 * 1024;
  for (uintptr_t addr = 0x0; addr < kLowMemoryLimit; addr += page_size) {
    EXPECT_FALSE(test_helper::TryRead(addr));
  }
}

TEST(Task, CantWriteLowAddresses) {
  if (!test_helper::IsStarnix()) {
    GTEST_SKIP();
  }

  const size_t page_size = SAFE_SYSCALL(sysconf(_SC_PAGE_SIZE));
  constexpr uintptr_t kLowMemoryLimit = 16 * 1024 * 1024;
  for (uintptr_t addr = 0x0; addr < kLowMemoryLimit; addr += page_size) {
    EXPECT_FALSE(test_helper::TryWrite(addr));
  }
}

class CloneAndExecTest : public ::testing::Test {
 protected:
  void SetUp() { clone_exec_helper_ = GetTestResourcePath(kCloneExecHelperBinary); }

  void CloneAndExec(int clone_flags, const std::vector<std::string>& arguments) {
    // Clone the process, with the caller-supplied flags.
    int child_pid = static_cast<int>(SAFE_SYSCALL(
        syscall(SYS_clone, clone_flags | SIGCHLD, nullptr, nullptr, nullptr, nullptr)));

    if (child_pid == 0) {
      // This is the child process, so exec() the specified command.
      std::vector<char*> args;
      args.push_back(clone_exec_helper_.data());
      for (const std::string& argument : arguments) {
        args.push_back(const_cast<char*>(argument.data()));
      }
      args.push_back(nullptr);
      char* const envp[] = {nullptr};

      SAFE_SYSCALL(execve(clone_exec_helper_.c_str(), args.data(), envp));
      _exit(EXIT_FAILURE);
    }

    // This is the parent process. Wait for the child process to complete, then return to the caller
    // to perform test validation.
    int wstatus = 0;
    SAFE_SYSCALL(waitpid(child_pid, &wstatus, 0));
    if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
      ADD_FAILURE() << "wait_status: WIFEXITED(wstatus) = " << WIFEXITED(wstatus)
                    << ", WEXITSTATUS(wstatus) = " << WEXITSTATUS(wstatus)
                    << ", WTERMSIG(wstatus) = " << WTERMSIG(wstatus);
    }
  }

  static std::string GetCurrentWorkingDirectory() {
    std::string cwd = get_current_dir_name();
    if (cwd.empty()) {
      _exit(EXIT_FAILURE);
    }
    return cwd;
  }

  static std::string GetTestResourcePath(const std::string& resource) {
    std::filesystem::path test_file = std::filesystem::path("data/tests/deps") / resource;

    std::error_code ec;
    bool file_exists = std::filesystem::exists(test_file, ec);
    EXPECT_FALSE(ec) << "failed to check if file exists: " << ec;

    if (!file_exists) {
      char self_path[PATH_MAX];
      realpath("/proc/self/exe", self_path);
      std::filesystem::path directory = std::filesystem::path(self_path).parent_path();
      return directory / resource;
    }

    return test_file;
  }

  static constexpr char kCloneExecHelperBinary[] = "clone_exec_helper";

  std::string clone_exec_helper_;
};

TEST_F(CloneAndExecTest, ExecUnsharesCloneFiles) {
  // Fork into a subprocess from which to `clone(CLONE_FILES)`, to avoid breaking the main test
  // process if things go awry.
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    // Open a temporary file to use as the "canary" for the FD table remaining shared.
    auto fd = test_helper::ScopedTempFD();
    ASSERT_THAT(fcntl(fd.fd(), F_GETFD), SyscallSucceeds());

    // The child process will run the helper with a command to close `fd`.
    std::vector<std::string> args{"close_fd", std::to_string(fd.fd())};
    CloneAndExec(CLONE_FILES, args);

    // Verify that the FD is still open in our FD table.
    EXPECT_THAT(fcntl(fd.fd(), F_GETFD), SyscallSucceeds());

    _exit(testing::Test::HasFailure());
  });

  ASSERT_TRUE(helper.WaitForChildren());
}

TEST_F(CloneAndExecTest, ExecDoesNotUnshareCloneFs) {
  // Fork into a subprocess from which to `clone(CLONE_FS)`, to avoid breaking the main test
  // process if things go awry.
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    // The child process will run the helper with a command-line to modify the current working
    // directory.
    std::string original_cwd = GetCurrentWorkingDirectory();

    // Create a temporary directory to use as the new CWD.
    test_helper::ScopedTempDir new_cwd;
    std::vector<std::string> args{"set_cwd", new_cwd.path()};
    CloneAndExec(CLONE_FS, args);

    // Verify that this process' current working directory has changed.
    EXPECT_EQ(new_cwd.path(), GetCurrentWorkingDirectory());

    _exit(testing::Test::HasFailure());
  });

  ASSERT_TRUE(helper.WaitForChildren());
}

TEST_F(CloneAndExecTest, ChildWithCloneFsCanChangeCwd) {
  // Fork into a subprocess from which to `clone(CLONE_FS)`, to avoid breaking the main test
  // process.
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    // The child process will change its current working directory from the original value.
    std::string original_cwd = GetCurrentWorkingDirectory();

    // Create a temporary directory to use as the new CWD.
    test_helper::ScopedTempDir new_cwd;

    // Fork the child with CLONE_FS.
    int child_pid = static_cast<int>(
        SAFE_SYSCALL(syscall(SYS_clone, CLONE_FS | SIGCHLD, nullptr, nullptr, nullptr, nullptr)));

    if (child_pid == 0) {
      // This is the child process, so change the current working directory.
      if (chdir(new_cwd.path().c_str()) != 0) {
        fprintf(stderr, "Failed to chdir to %s: %d (%s)\n", new_cwd.path().c_str(), errno,
                strerror(errno));
        exit(EXIT_FAILURE);
      }
      _exit(0);
    }

    // This is the parent process. Wait for the child process to complete, then check whether the
    // current working directory has changed.
    int wstatus = 0;
    SAFE_SYSCALL(waitpid(child_pid, &wstatus, 0));
    if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
      ADD_FAILURE() << "wait_status: WIFEXITED(wstatus) = " << WIFEXITED(wstatus)
                    << ", WEXITSTATUS(wstatus) = " << WEXITSTATUS(wstatus)
                    << ", WTERMSIG(wstatus) = " << WTERMSIG(wstatus);
    }

    // Verify that this process' current working directory has changed.
    EXPECT_NE(original_cwd, GetCurrentWorkingDirectory());

    _exit(testing::Test::HasFailure());
  });

  ASSERT_TRUE(helper.WaitForChildren());
}

class DumpableTest : public ::testing::Test {
 protected:
  void SetUp() {
    if (!test_helper::HasSysAdmin()) {
      GTEST_SKIP() << "test requires root privileges";
    }

    FILE* fp = fopen("/proc/sys/fs/suid_dumpable", "r");
    EXPECT_NE(fp, nullptr);
    // TODO(https://fxbug.dev/322874210): EXPECT that the read succeeds, do not
    // hard-code a value.
    if (fscanf(fp, "%d", &dumpable_default_) != 1) {
      dumpable_default_ = 0;
    }

    fclose(fp);
  }
  int dumpable_default_ = -1;
};

TEST_F(DumpableTest, DumpablePersistsAcrossFork) {
  test_helper::ForkHelper helper;
  helper.RunInForkedProcess([&] {
    SAFE_SYSCALL(prctl(PR_SET_DUMPABLE, 1));

    pid_t child_pid = SAFE_SYSCALL(fork());
    if (child_pid == 0) {
      EXPECT_EQ(prctl(PR_GET_DUMPABLE), 1);
      exit(testing::Test::HasFailure());
    }

    int status;
    SAFE_SYSCALL(waitpid(child_pid, &status, 0));
    EXPECT_TRUE(WIFEXITED(status));
    EXPECT_EQ(WEXITSTATUS(status), 0);
  });

  EXPECT_TRUE(helper.WaitForChildren());
}

TEST_F(DumpableTest, DumpableDropsOnUserChange) {
  for (size_t combination = 0b00000000; combination <= 0b11111111; combination++) {
    uid_t ruid, euid, suid, fuid;
    gid_t rgid, egid, sgid, fgid;

    ruid = (combination & 0b00000001) ? kUser1Uid : 0;
    euid = (combination & 0b00000010) ? kUser1Uid : 0;
    suid = (combination & 0b00000100) ? kUser1Uid : 0;
    fuid = (combination & 0b00001000) ? kUser1Uid : 0;
    rgid = (combination & 0b00010000) ? kUser1Gid : 0;
    egid = (combination & 0b00100000) ? kUser1Gid : 0;
    sgid = (combination & 0b01000000) ? kUser1Gid : 0;
    fgid = (combination & 0b10000000) ? kUser1Gid : 0;

    bool expected_change =
        (euid == kUser1Uid || egid == kUser1Gid || fuid == kUser1Uid || fgid == kUser1Gid);

    test_helper::ForkHelper helper;
    helper.RunInForkedProcess([&] {
      SCOPED_TRACE(fxl::StringPrintf("resfsuid: (%d, %d, %d, %d) resfsgid: (%d, %d, %d, %d)", ruid,
                                     euid, suid, fuid, rgid, egid, sgid, fgid));
      SAFE_SYSCALL(prctl(PR_SET_DUMPABLE, 1));

      SAFE_SYSCALL(setresgid(rgid, egid, sgid));
      SAFE_SYSCALL(setfsgid(fgid));
      SAFE_SYSCALL(setfsuid(fuid));
      SAFE_SYSCALL(setresuid(ruid, euid, suid));

      int dumpable = prctl(PR_GET_DUMPABLE);
      if (expected_change) {
        EXPECT_EQ(dumpable, dumpable_default_);
      } else {
        EXPECT_EQ(dumpable, 1);
      }
    });

    EXPECT_TRUE(helper.WaitForChildren());
  }
}

TEST(Task, SetgroupsWithoutCapSetgidFails) {
  if (!test_helper::HasSysAdmin()) {
    GTEST_SKIP() << "test requires root privileges";
  }

  test_helper::ForkHelper helper;

  helper.RunInForkedProcess([]() {
    // Dropping CAP_SETGID should be sufficient to cause setgroups() to fail.
    test_helper::UnsetCapability(CAP_SETGID);

    gid_t groups[] = {kUser1Gid};
    EXPECT_THAT(setgroups(1, groups), SyscallFailsWithErrno(EPERM));
  });
  EXPECT_TRUE(helper.WaitForChildren());
}

TEST(Task, SetgroupsWithCapSetgidSucceeds) {
  if (!test_helper::HasSysAdmin()) {
    GTEST_SKIP() << "test requires root privileges";
  }

  test_helper::ForkHelper helper;

  helper.RunInForkedProcess([]() {
    // Change to non-root user while preserving capabilities, and re-enable CAP_SETGID.
    SAFE_SYSCALL(prctl(PR_SET_KEEPCAPS, 1));
    SAFE_SYSCALL(setresuid(kUser1Uid, kUser1Uid, kUser1Uid));
    test_helper::SetCapabilityEffective(CAP_SETGID);

    gid_t groups[] = {kUser1Gid};
    EXPECT_THAT(setgroups(1, groups), SyscallSucceeds());
  });
  EXPECT_TRUE(helper.WaitForChildren());
}
