// Copyright 2016 The Bazel 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.

/**
 * This is PID 1 inside the sandbox environment and runs in a separate user,
 * mount, UTS, IPC and PID namespace.
 */

#include "src/main/tools/linux-sandbox-pid1.h"

#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <libgen.h>
#include <mntent.h>
#include <net/if.h>
#include <pwd.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <ctime>
#include <string>
#include <unordered_set>

#ifndef MS_REC
// Some systems do not define MS_REC in sys/mount.h. We might be able to grab it
// from linux/fs.h instead (cf. #2667).
#include <linux/fs.h>
#endif

#ifndef TEMP_FAILURE_RETRY
// Some C standard libraries like musl do not define this macro, so we'll
// include our own version for compatibility.
#define TEMP_FAILURE_RETRY(exp)            \
  ({                                       \
    decltype(exp) _rc;                     \
    do {                                   \
      _rc = (exp);                         \
    } while (_rc == -1 && errno == EINTR); \
    _rc;                                   \
  })
#endif  // TEMP_FAILURE_RETRY

#include "src/main/tools/linux-sandbox-options.h"
#include "src/main/tools/linux-sandbox.h"
#include "src/main/tools/logging.h"
#include "src/main/tools/process-tools.h"

static int global_child_pid;

// Helper methods
static void CreateFile(const char* path) {
  int handle = open(path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, 0666);
  if (handle < 0) {
    DIE("open");
  }
  if (close(handle) < 0) {
    DIE("close");
  }
}

// Creates an empty file at 'path' by hard linking it from a known empty file.
// This is over two times faster than creating empty files via open() on
// certain filesystems (e.g. XFS).
static void LinkFile(const char* path) {
  if (link("tmp/empty_file", path) < 0) {
    if (errno == EEXIST) {
      // Try to remove the existing file first.
      if (unlink(path) < 0) {
        DIE("unlink %s", path);
      }
      if (link("tmp/empty_file", path) == 0) {
        return;
      }
    }
    DIE("link %s", path);
  }
}

// Creates a symlink from 'target' -> 'path'. If 'path' already existed then
// unlink and try again.
static void SymlinkFile(const char* target, const char* path) {
  if (symlink(target, path) < 0) {
    if (errno == EEXIST) {
      // Try to remove the existing file first.
      if (unlink(path) < 0) {
        DIE("unlink %s", path);
      }
      if (symlink(target, path) == 0) {
        return;
      }
    }
    DIE("symlink %s", path);
  }
}

// Recursively creates the file or directory specified in "path" and its parent
// directories.
// Return -1 on failure and sets errno to:
//    EINVAL   path is null
//    ENOTDIR  path exists and is not a directory
//    EEXIST   path exists and is a directory
//    ENOENT   stat call with the path failed
static int CreateTarget(const char* path, bool is_directory) {
  if (path == NULL) {
    errno = EINVAL;
    return -1;
  }

  struct stat sb;
  // If the path already exists...

  if (stat(path, &sb) == 0) {
    if (is_directory && S_ISDIR(sb.st_mode)) {
      // and it's a directory and supposed to be a directory, we're done here.
      return 0;
    } else if (!is_directory && S_ISREG(sb.st_mode)) {
      // and it's a regular file and supposed to be one, we're done here.
      return 0;
    } else {
      // otherwise something is really wrong.
      errno = is_directory ? ENOTDIR : EEXIST;
      return -1;
    }
  } else {
    // If stat failed because of any error other than "the path does not exist",
    // this is an error.
    if (errno != ENOENT) {
      return -1;
    }
  }

  // Create the parent directory.
  {
    char *buf, *dir;

    if (!(buf = strdup(path))) DIE("strdup");

    dir = dirname(buf);
    if (CreateTarget(dir, true) < 0) {
      DIE("CreateTarget %s", dir);
    }

    free(buf);
  }

  if (is_directory) {
    if (mkdir(path, 0755) < 0) {
      DIE("mkdir(%s)", path);
    }
  } else {
    LinkFile(path);
  }

  return 0;
}

static void SetupSelfDestruction(int* pipe_to_parent) {
  // We could also poll() on the pipe fd to find out when the parent goes away,
  // and rely on SIGCHLD interrupting that otherwise. That might require us to
  // install some trivial handler for SIGCHLD. Using O_ASYNC to turn the pipe
  // close into SIGIO may also work. Another option is signalfd, although that's
  // almost as obscure as this prctl.
  if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) {
    DIE("prctl");
  }

  // Switch to a new process group, otherwise our process group will still refer
  // to the outer PID namespace. We might then accidentally kill our parent by a
  // call to e.g. `kill(0, sig)`.
  if (setpgid(0, 0) < 0) {
    DIE("setpgid");
  }

  // Verify that the parent still lives.
  SignalPipe(pipe_to_parent);
}

static void SetupMountNamespace() {
  // Fully isolate our mount namespace private from outside events, so that
  // mounts in the outside environment do not affect our sandbox.
  if (mount(nullptr, "/", nullptr, MS_REC | MS_PRIVATE, nullptr) < 0) {
    DIE("mount");
  }
}

static void SetupUserNamespace() {
  // Disable needs for CAP_SETGID.
  struct stat sb;
  if (stat("/proc/self/setgroups", &sb) == 0) {
    WriteFile("/proc/self/setgroups", "deny");
  } else {
    // Ignore ENOENT, because older Linux versions do not have this file (but
    // also do not require writing to it).
    if (errno != ENOENT) {
      DIE("stat(/proc/self/setgroups");
    }
  }

  uid_t inner_uid;
  gid_t inner_gid;
  if (opt.fake_root) {
    // Change our username to 'root'.
    inner_uid = 0;
    inner_gid = 0;
  } else if (opt.fake_username) {
    // Change our username to 'nobody'.
    struct passwd pwd;
    char buf[1024];
    size_t buflen = sizeof(buf);
    struct passwd* result;
    if (getpwnam_r("nobody", &pwd, buf, buflen, &result) != 0 ||
        result == nullptr) {
      DIE("getpwnam_r for nobody failed");
    }

    inner_uid = pwd.pw_uid;
    inner_gid = pwd.pw_gid;
  } else {
    // Do not change the username inside the sandbox.
    inner_uid = global_outer_uid;
    inner_gid = global_outer_gid;
  }
  if (opt.enable_pty) {
    // Change the group to "tty" regardless of what was previously set
    struct group grp;
    char buf[256];
    size_t buflen = sizeof(buf);
    struct group* result;
    getgrnam_r("tty", &grp, buf, buflen, &result);
    if (result == nullptr) {
      DIE("getgrnam_r");
    }
    inner_gid = grp.gr_gid;
  }

  WriteFile("/proc/self/uid_map", "%u %u 1\n", inner_uid, global_outer_uid);
  WriteFile("/proc/self/gid_map", "%u %u 1\n", inner_gid, global_outer_gid);
}

static void SetupUtsNamespace() {
  if (sethostname("localhost", 9) < 0) {
    DIE("sethostname");
  }

  if (setdomainname("localdomain", 11) < 0) {
    DIE("setdomainname");
  }
}

static void MountFilesystems() {
  // An attempt to mount the sandbox in tmpfs will always fail, so this block is
  // slightly redundant with the next mount() check, but dumping the mount()
  // syscall is incredibly cryptic, so we explicitly check against and warn
  // about attempts to use tmpfs.
  for (const std::string& tmpfs_dir : opt.tmpfs_dirs) {
    if (opt.working_dir.find(tmpfs_dir) == 0) {
      DIE("The sandbox working directory cannot be below a path where we mount "
          "tmpfs (you requested mounting %s in %s). Is your --output_base= "
          "below one of your --sandbox_tmpfs_path values?",
          opt.working_dir.c_str(), tmpfs_dir.c_str());
    }
  }

  std::unordered_set<std::string> bind_mount_sources;

  for (size_t i = 0; i < opt.bind_mount_sources.size(); i++) {
    const std::string& source = opt.bind_mount_sources.at(i);
    bind_mount_sources.insert(source);
    const std::string& target = opt.bind_mount_targets.at(i);
    PRINT_DEBUG("bind mount: %s -> %s", source.c_str(), target.c_str());
    if (mount(source.c_str(), target.c_str(), nullptr, MS_BIND | MS_REC,
              nullptr) < 0) {
      DIE("mount(%s, %s, nullptr, MS_BIND | MS_REC, nullptr)", source.c_str(),
          target.c_str());
    }
  }

  for (const std::string& tmpfs_dir : opt.tmpfs_dirs) {
    PRINT_DEBUG("tmpfs: %s", tmpfs_dir.c_str());
    if (mount("tmpfs", tmpfs_dir.c_str(), "tmpfs",
              MS_NOSUID | MS_NODEV | MS_NOATIME, nullptr) < 0) {
      DIE("mount(tmpfs, %s, tmpfs, MS_NOSUID | MS_NODEV | MS_NOATIME, nullptr)",
          tmpfs_dir.c_str());
    }
  }

  for (const std::string& writable_file : opt.writable_files) {
    PRINT_DEBUG("writable: %s", writable_file.c_str());
    if (bind_mount_sources.find(writable_file) != bind_mount_sources.end()) {
      // Bind mount sources contained in writable_files will be kept writable in
      // MakeFileSystemMostlyReadOnly, but have already been mounted at this
      // point.
      continue;
    }
    if (mount(writable_file.c_str(), writable_file.c_str(), nullptr,
              MS_BIND | MS_REC, nullptr) < 0) {
      DIE("mount(%s, %s, nullptr, MS_BIND | MS_REC, nullptr)",
          writable_file.c_str(), writable_file.c_str());
    }
  }

  // Make sure that the working directory is writable (unlike most of the rest
  // of the file system, which is read-only by default). The easiest way to do
  // this is by bind-mounting it upon itself.
  PRINT_DEBUG("working dir: %s", opt.working_dir.c_str());

  if (mount(opt.working_dir.c_str(), opt.working_dir.c_str(), nullptr, MS_BIND,
            nullptr) < 0) {
    DIE("mount(%s, %s, nullptr, MS_BIND, nullptr)", opt.working_dir.c_str(),
        opt.working_dir.c_str());
  }
}

// We later remount everything read-only, except the paths for which this method
// returns true.
static bool ShouldBeWritable(const std::string& mnt_dir) {
  if (mnt_dir == opt.working_dir) {
    return true;
  }

  if (opt.enable_pty && mnt_dir == "/dev/pts") {
    return true;
  }

  for (const std::string& writable_file : opt.writable_files) {
    if (mnt_dir == writable_file) {
      return true;
    }
  }

  for (const std::string& tmpfs_dir : opt.tmpfs_dirs) {
    if (mnt_dir == tmpfs_dir) {
      return true;
    }
  }

  return false;
}

// Makes the whole filesystem read-only, except for the paths for which
// ShouldBeWritable returns true.
static void MakeFilesystemMostlyReadOnly() {
  FILE* mounts = setmntent("/proc/self/mounts", "r");
  if (mounts == nullptr) {
    DIE("setmntent");
  }

  struct mntent* ent;
  while ((ent = getmntent(mounts)) != nullptr) {
    int mountFlags = MS_BIND | MS_REMOUNT;

    // MS_REMOUNT does not allow us to change certain flags. This means, we have
    // to first read them out and then pass them in back again. There seems to
    // be no better way than this (an API for just getting the mount flags of a
    // mount entry as a bitmask would be great).
    if (hasmntopt(ent, "nodev") != nullptr) {
      mountFlags |= MS_NODEV;
    }
    if (hasmntopt(ent, "noexec") != nullptr) {
      mountFlags |= MS_NOEXEC;
    }
    if (hasmntopt(ent, "nosuid") != nullptr) {
      mountFlags |= MS_NOSUID;
    }
    if (hasmntopt(ent, "noatime") != nullptr) {
      mountFlags |= MS_NOATIME;
    }
    if (hasmntopt(ent, "nodiratime") != nullptr) {
      mountFlags |= MS_NODIRATIME;
    }
    if (hasmntopt(ent, "relatime") != nullptr) {
      mountFlags |= MS_RELATIME;
    }

    if (!ShouldBeWritable(ent->mnt_dir)) {
      mountFlags |= MS_RDONLY;
    }

    PRINT_DEBUG("remount %s: %s", (mountFlags & MS_RDONLY) ? "ro" : "rw",
                ent->mnt_dir);
    // The remount races with concurrent path lookups elsewhere on the host:
    // walking through a symlink calls touch_atime(), which briefly bumps the
    // per-mount writer counter (mnt_get_write_access -> mnt_inc_writers).
    // MS_BIND|MS_REMOUNT|MS_RDONLY goes through mnt_hold_writers() which
    // returns -EBUSY if that counter is non-zero. The window is tiny but on
    // active mounts (especially "/") it can sometimes hit. Retry on EBUSY.
    // This behavior mimics runc's handling of EBUSY during readonly remounts:
    // https://github.com/opencontainers/runc/blob/eb7eaf19b6eec5d1143b257057899e4a7b738c81/libcontainer/rootfs_linux.go#L1305-L1309
    int rc;
    for (int i = 0; i < 5; ++i) {
      rc = mount(nullptr, ent->mnt_dir, nullptr, mountFlags, nullptr);
      if (rc == 0 || errno != EBUSY || i == 4) break;
      struct timespec delay;
      delay.tv_sec = 0;
      delay.tv_nsec = 100 * 1000 * 1000;  // 100 milliseconds
      nanosleep(&delay, nullptr);
    }
    if (rc < 0) {
      // If we get EACCES or EPERM, this might be a mount-point for which we
      // don't have read access. Not much we can do about this, but it also
      // won't do any harm, so let's go on. The same goes for EINVAL or ENOENT,
      // which are fired in case a later mount overlaps an earlier mount, e.g.
      // consider the case of /proc, /proc/sys/fs/binfmt_misc and /proc, with
      // the latter /proc being the one that an outer sandbox has mounted on
      // top of its parent /proc. In that case, we're not allowed to remount
      // /proc/sys/fs/binfmt_misc, because it is hidden. If we get ESTALE, the
      // mount is a broken NFS mount. In the ideal case, the user would either
      // fix or remove that mount, but in cases where that's not possible, we
      // should just ignore it. Similarly, one can get ENODEV in case of
      // autofs/automount failure.
      switch (errno) {
        case EACCES:
        case EPERM:
        case EINVAL:
        case ENOENT:
        case ESTALE:
        case ENODEV:
          PRINT_DEBUG(
              "remount(nullptr, %s, nullptr, %d, nullptr) failure (%m) ignored",
              ent->mnt_dir, mountFlags);
          break;
        default:
          DIE("remount(nullptr, %s, nullptr, %d, nullptr)", ent->mnt_dir,
              mountFlags);
      }
    }
  }

  endmntent(mounts);
}

static void MountProcAndSys() {
  if (opt.hermetic) {
    if (CreateTarget("proc", true) < 0) {
      DIE("CreateTarget proc");
    }
    if (mount("proc", "proc", "proc", MS_NODEV | MS_NOEXEC | MS_NOSUID,
              nullptr) < 0) {
      DIE("mount proc");
    }

    if (CreateTarget("sys", true) < 0) {
      DIE("CreateTarget sys");
    }

    if (opt.create_netns != NO_NETNS) {
      if (mount("none", "sys", "sysfs",
                MS_NOEXEC | MS_NOSUID | MS_NODEV | MS_RDONLY, nullptr) < 0) {
        DIE("mount sys");
      }
    } else {
      // In hermetic mode without a new network namespace, we cannot mount a
      // fresh sysfs because we share the network namespace with the host (this
      // fails with EPERM in a user namespace). Bind-mount the host /sys
      // instead.
      if (mount("/sys", "sys", nullptr, MS_BIND | MS_REC, nullptr) < 0) {
        DIE("bind mount /sys to sys");
      }
    }
  } else {
    if (mount("proc", "/proc", "proc", MS_NODEV | MS_NOEXEC | MS_NOSUID,
              nullptr) < 0) {
      DIE("mount /proc");
    }

    if (opt.create_netns != NO_NETNS) {
      if (mount("none", "/sys", "sysfs",
                MS_NOEXEC | MS_NOSUID | MS_NODEV | MS_RDONLY, nullptr) < 0) {
        DIE("mount /sys");
      }
    }
  }
}

static void SetupNetworking() {
  // When running in a separate network namespace, enable the loopback interface
  // because some application may want to use it.
  if (opt.create_netns == NETNS_WITH_LOOPBACK) {
    int fd;
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
      DIE("socket");
    }

    struct ifreq ifr = {};
    strncpy(ifr.ifr_name, "lo", IF_NAMESIZE);

    // Verify that name is valid.
    if (if_nametoindex(ifr.ifr_name) == 0) {
      DIE("if_nametoindex");
    }

    // Enable the interface.
    ifr.ifr_flags |= IFF_UP;
    if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
      DIE("ioctl");
    }

    if (close(fd) < 0) {
      DIE("close");
    }
  }

  if (opt.create_netns != NO_NETNS && opt.fake_root) {
    // Allow IPPROTO_ICMP sockets when already allowed outside of the namespace.
    // In a namespace, /proc/sys/net/ipv4/ping_group_range is reset to the
    // default of 1 0, which does not match any groups. However, it can only be
    // overridden when the namespace has a fake root. This may be a kernel bug.
    WriteFile("/proc/sys/net/ipv4/ping_group_range", "0 0");
  }
}

static void EnterWorkingDirectory() {
  std::string path = opt.working_dir;
  if (opt.hermetic) {
    path = path.substr(opt.sandbox_root.size() + 1);
  }

  if (chdir(path.c_str()) < 0) {
    DIE("chdir(%s)", path.c_str());
  }
}

static void ForwardSignal(int signum) { kill(-global_child_pid, signum); }

static void SpawnChild() {
  PRINT_DEBUG("calling fork...");
  global_child_pid = fork();

  if (global_child_pid < 0) {
    DIE("fork()");
  } else if (global_child_pid == 0) {
    // Put the child into its own process group.
    if (setpgid(0, 0) < 0) {
      DIE("setpgid");
    }

    // Try to assign our terminal to the child process.
    if (tcsetpgrp(STDIN_FILENO, getpgrp()) < 0 && errno != ENOTTY) {
      DIE("tcsetpgrp");
    }

    // Unblock all signals, restore default handlers.
    ClearSignalMask();

    // Close the file PRINT_DEBUG writes to.
    // Must happen late enough so we don't lose any debugging output.
    if (global_debug) {
      fclose(global_debug);
      global_debug = nullptr;
    }

    // Force umask to include read and execute for everyone, to make output
    // permissions predictable.
    umask(022);

    // argv[] passed to execve() must be a null-terminated array.
    opt.args.push_back(nullptr);

    if (execvp(opt.args[0], opt.args.data()) < 0) {
      DIE("execvp(%s, %p)", opt.args[0], opt.args.data());
    }
  } else {
    PRINT_DEBUG("child started with PID %d", global_child_pid);
  }
}

static int WaitForChild() {
  while (true) {
    // Wait for some process to exit. This includes reparented processes in our
    // PID namespace.
    int status;
    const pid_t pid = TEMP_FAILURE_RETRY(wait(&status));

    if (pid < 0) {
      // We don't expect any errors besides EINTR. In particular, ECHILD should
      // be impossible because we haven't yet seen global_child_pid exit.
      DIE("wait");
    }

    PRINT_DEBUG("wait returned pid=%d, status=0x%02x", pid, status);

    // If this isn't our child's PID, there's nothing further to do; we've
    // successfully reaped a zombie.
    if (pid != global_child_pid) {
      continue;
    }

    // If the child exited due to a signal, log that fact and exit with the same
    // status.
    if (WIFSIGNALED(status)) {
      const int signal = WTERMSIG(status);
      PRINT_DEBUG("child exited due to signal %d", WTERMSIG(status));
      return 128 + signal;
    }

    // Otherwise it must have exited normally.
    const int exit_code = WEXITSTATUS(status);
    PRINT_DEBUG("child exited normally with code %d", exit_code);
    return exit_code;
  }
}

static void MountSandboxAndGoThere() {
  if (mount(opt.sandbox_root.c_str(), opt.sandbox_root.c_str(), nullptr,
            MS_BIND | MS_NOSUID, nullptr) < 0) {
    DIE("mount");
  }
  if (chdir(opt.sandbox_root.c_str()) < 0) {
    DIE("chdir(%s)", opt.sandbox_root.c_str());
  }
}

static void CreateEmptyFile() {
  // This is used as the base for bind mounting.
  if (CreateTarget("tmp", true) < 0) {
    DIE("CreateTarget tmp")
  }
  CreateFile("tmp/empty_file");
}

static void MountDev() {
  if (CreateTarget("dev", true) < 0) {
    DIE("CreateTarget dev");
  }

  const char* devs[] = {"/dev/null", "/dev/random", "/dev/urandom",
                        "/dev/zero", "/dev/full",   NULL};
  for (int i = 0; devs[i] != NULL; i++) {
    LinkFile(devs[i] + 1);
    PRINT_DEBUG("bind mount: %s -> dev/%s", devs[i], devs[i] + 5);
    if (mount(devs[i], devs[i] + 1, NULL, MS_BIND, NULL) < 0) {
      DIE("mount %s", devs[i]);
    }
  }

  if (CreateTarget("dev/shm", true) == 0) {
    PRINT_DEBUG("mounting tmpfs on dev/shm");
    if (mount("tmpfs", "dev/shm", "tmpfs", MS_NOSUID | MS_NODEV, "mode=1777") <
        0) {
      DIE("mount dev/shm");
    }
  }

  SymlinkFile("/proc/self/fd", "dev/fd");
  SymlinkFile("/proc/self/fd/0", "dev/stdin");
  SymlinkFile("/proc/self/fd/1", "dev/stdout");
  SymlinkFile("/proc/self/fd/2", "dev/stderr");
}

static void MountAllMounts() {
  for (const std::string& tmpfs_dir : opt.tmpfs_dirs) {
    PRINT_DEBUG("tmpfs: %s", tmpfs_dir.c_str());
    if (mount("tmpfs", tmpfs_dir.c_str(), "tmpfs",
              MS_NOSUID | MS_NODEV | MS_NOATIME, nullptr) < 0) {
      DIE("mount(tmpfs, %s, tmpfs, MS_NOSUID | MS_NODEV | MS_NOATIME, nullptr)",
          tmpfs_dir.c_str());
    }
  }

  // Make sure that the working directory is writable (unlike most of the rest
  // of the file system, which is read-only by default). The easiest way to do
  // this is by bind-mounting it upon itself.
  if (mount(opt.working_dir.c_str(), opt.working_dir.c_str(), nullptr, MS_BIND,
            nullptr) < 0) {
    DIE("mount(%s, %s, nullptr, MS_BIND, nullptr)", opt.working_dir.c_str(),
        opt.working_dir.c_str());
  }

  for (int i = 0; i < (signed)opt.bind_mount_sources.size(); i++) {
    if (global_debug) {
      if (strcmp(opt.bind_mount_sources[i].c_str(),
                 opt.bind_mount_targets[i].c_str()) == 0) {
        // The file is mounted to the same path inside the sandbox, as outside
        // (e.g. /home/user -> <sandbox>/home/user), so we'll just show a
        // simplified version of the mount command.
        PRINT_DEBUG("mount: %s\n", opt.bind_mount_sources[i].c_str());
      } else {
        // The file is mounted to a custom location inside the sandbox.
        // Create a user-friendly string for the sandboxed path and show it.
        const std::string user_friendly_mount_target("<sandbox>" +
                                                     opt.bind_mount_targets[i]);
        PRINT_DEBUG("mount: %s -> %s\n", opt.bind_mount_sources[i].c_str(),
                    user_friendly_mount_target.c_str());
      }
    }
    const std::string full_sandbox_path(opt.sandbox_root +
                                        opt.bind_mount_targets[i]);

    struct stat sb;
    if (stat(opt.bind_mount_sources[i].c_str(), &sb) < 0) {
      DIE("stat");
    }
    bool IsDirectory = S_ISDIR(sb.st_mode);
    if (CreateTarget(full_sandbox_path.c_str(), IsDirectory) < 0) {
      DIE("CreateTarget %s", full_sandbox_path.c_str());
    }
    int result =
        mount(opt.bind_mount_sources[i].c_str(), full_sandbox_path.c_str(),
              NULL, MS_REC | MS_BIND | MS_RDONLY, NULL);
    if (result != 0) {
      DIE("mount");
    }
  }
  for (const std::string& writable_file : opt.writable_files) {
    PRINT_DEBUG("writable: %s", writable_file.c_str());
    if (mount(writable_file.c_str(), writable_file.c_str(), nullptr,
              MS_BIND | MS_REC, nullptr) < 0) {
      DIE("mount(%s, %s, nullptr, MS_BIND | MS_REC, nullptr)",
          writable_file.c_str(), writable_file.c_str());
    }
  }
}

static void ChangeRoot() {
  // move the real root to old_root, then detach it
  char old_root[16] = "old-root-XXXXXX";
  if (mkdtemp(old_root) == NULL) {
    perror("mkdtemp");
    DIE("mkdtemp returned NULL\n");
  }
  // pivot_root has no wrapper in libc, so we need syscall()
  if (syscall(SYS_pivot_root, ".", old_root) < 0) {
    DIE("syscall");
  }
  if (chroot(".") < 0) {
    DIE("chroot");
  }
  if (umount2(old_root, MNT_DETACH) < 0) {
    DIE("umount2");
  }
  if (rmdir(old_root) < 0) {
    DIE("rmdir");
  }
}

int Pid1Main(void* args) {
  PRINT_DEBUG("Pid1Main started");

  Pid1Args pid1Args = *(static_cast<Pid1Args*>(args));

  if (getpid() != 1) {
    DIE("Using PID namespaces, but we are not PID 1");
  }

  // Before pid1 spawns a child pid2, we want to wait for the parent process to
  // move pid1 to the cgroup so that pid2 will be created in the same cgroup.
  WaitPipe(pid1Args.pipe_from_parent);

  // Start with default signal handlers and an empty signal mask.
  ClearSignalMask();

  SetupSelfDestruction(pid1Args.pipe_to_parent);

  // Sandbox ourselves.
  SetupMountNamespace();
  SetupUserNamespace();
  if (opt.fake_hostname) {
    SetupUtsNamespace();
  }

  if (opt.hermetic) {
    MountSandboxAndGoThere();
    CreateEmptyFile();
    MountDev();
    MountProcAndSys();
    MountAllMounts();
    ChangeRoot();
  } else {
    MountFilesystems();
    MakeFilesystemMostlyReadOnly();
    MountProcAndSys();
  }
  SetupNetworking();
  EnterWorkingDirectory();

  // Ignore terminal signals; we hand off the terminal to the child in
  // SpawnChild below.
  IgnoreSignal(SIGTTIN);
  IgnoreSignal(SIGTTOU);

  // Fork the child process.
  SpawnChild();

  // Forward requests to shut down gracefully to the child.
  InstallSignalHandler(SIGTERM, ForwardSignal);

  // Note that there's no need to kill any remaining descendant processes; they
  // are in our PID namespace and the kernel will send them SIGKILL
  // automatically once we exit.
  return WaitForChild();
}
