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

/**
 * linux-sandbox runs commands in a restricted environment where they are
 * subject to a few rules:
 *
 *  - The entire filesystem is made read-only.
 *  - The working directory (-W) will be made read-write, though.
 *  - Individual files or directories can be made writable (but not deletable)
 *    (-w).
 *  - If the process takes longer than the timeout (-T), it will be killed with
 *    SIGTERM. If it does not exit within the grace period (-t), it all of its
 *    children will be killed with SIGKILL.
 *  - tmpfs can be mounted on top of existing directories (-e).
 *  - If option -R is passed, the process will run as user 'root'.
 *  - If option -U is passed, the process will run as user 'nobody'.
 *  - Otherwise, the process runs using the current uid / gid.
 *  - If linux-sandbox itself gets killed, the process and all of its children
 *    will be killed.
 *  - If linux-sandbox's parent dies, it will kill itself, the process and all
 *    the children.
 *  - Network access is allowed, but can be disabled via -N.
 *  - The hostname and domainname will be set to "sandbox".
 *  - The process runs in its own PID namespace, so other processes on the
 *    system are invisible.
 */

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

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <algorithm>
#include <atomic>
#include <cinttypes>
#include <cstdint>
#include <string>
#include <vector>

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

uid_t global_outer_uid;
gid_t global_outer_gid;

// The PID of our child process, for use in signal handlers.
static std::atomic<pid_t> global_child_pid{0};
// Our parent's pid at the outset, to check if the original parent has exited.
pid_t initial_ppid;

// Must we politely ask the child to exit before we send it a SIGKILL (once we
// want it to exit)? Holds only zero or one.
static std::atomic<int> global_need_polite_sigterm{false};

#if __cplusplus >= 201703L
static_assert(global_child_pid.is_always_lock_free);
static_assert(global_need_polite_sigterm.is_always_lock_free);
#endif

// Make sure the child process does not inherit any accidentally left open file
// handles from our parent.
static void CloseFds() {
  DIR *fds = opendir("/proc/self/fd");
  if (fds == nullptr) {
    DIE("opendir");
  }

  while (1) {
    errno = 0;
    struct dirent *dent = readdir(fds);

    if (dent == nullptr) {
      if (errno != 0) {
        DIE("readdir");
      }
      break;
    }

    if (isdigit(dent->d_name[0])) {
      errno = 0;
      int fd = strtol(dent->d_name, nullptr, 10);

      // (1) Skip unparseable entries.
      // (2) Close everything except stdin, stdout, stderr and debug output.
      // (3) Do not accidentally close our directory handle.
      if (errno == 0 && fd > STDERR_FILENO &&
          (global_debug == NULL || fd != fileno(global_debug)) &&
          fd != dirfd(fds)) {
        if (close(fd) < 0) {
          DIE("close");
        }
      }
    }
  }

  if (closedir(fds) < 0) {
    DIE("closedir");
  }
}

static void MaybeAddChildProcessToCgroup(const pid_t pid) {
  for (const std::string &cgroups_dir : opt.cgroups_dirs) {
    PRINT_DEBUG("Adding process %d to cgroups dir %s", pid,
                cgroups_dir.c_str());
    WriteFile(cgroups_dir + "/cgroup.procs", "%d", pid);
  }
}

static void OnTimeoutOrTerm(int) {
  // Find the PID of the child, which main set up before installing us as a
  // signal handler.
  const pid_t child_pid = global_child_pid.load(std::memory_order_relaxed);

  // Figure out whether we should send a SIGTERM here. If so, we won't want to
  // next time we're called.
  const bool need_polite_sigterm =
      global_need_polite_sigterm.fetch_and(0, std::memory_order_relaxed);

  // If we're not supposed to ask politely, simply forcibly kill the child.
  if (!need_polite_sigterm) {
    kill(child_pid, SIGKILL);
    return;
  }

  // Otherwise make a polite request, then arrange to be called again after a
  // delay, at which point we'll send SIGKILL.
  //
  // Note that main sets us up as the signal handler for SIGALRM, and arranges
  // for this code path to be taken only if kill_delay_secs > 0.
  kill(child_pid, SIGTERM);
  alarm(opt.kill_delay_secs);
}

static pid_t SpawnPid1() {
  const int kStackSize = 1024 * 1024;
  std::vector<char> child_stack(kStackSize);

  PRINT_DEBUG("calling pipe(2)...");

  int pipe_from_child[2], pipe_to_child[2];
  if (pipe(pipe_from_child) < 0) {
    DIE("pipe");
  }
  if (pipe(pipe_to_child) < 0) {
      DIE("pipe");
    }

  int clone_flags =
      CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWPID | SIGCHLD;
  PRINT_DEBUG("Netns is %d", opt.create_netns);
  if (opt.create_netns != NO_NETNS) {
    clone_flags |= CLONE_NEWNET;
  }
  if (opt.fake_hostname) {
    clone_flags |= CLONE_NEWUTS;
  }

  // We use clone instead of unshare, because unshare sometimes fails with
  // EINVAL due to a race condition in the Linux kernel (see
  // https://lkml.org/lkml/2015/7/28/833).
  PRINT_DEBUG("calling clone(2)...");

  Pid1Args pid1Args;
  pid1Args.pipe_to_parent = pipe_from_child;
  pid1Args.pipe_from_parent = pipe_to_child;
  const pid_t child_pid = clone(Pid1Main, child_stack.data() + kStackSize,
                                clone_flags, &pid1Args);

  if (child_pid < 0) {
    DIE("clone");
  }

  MaybeAddChildProcessToCgroup(child_pid);
  // Signal the child that it can now proceed to spawn pid2.
  SignalPipe(pipe_to_child);

  PRINT_DEBUG("linux-sandbox-pid1 has PID %d", child_pid);

  // Wait for a signal from the child linux-sandbox-pid1 process; this proves to
  // the child process that we still existed after it ran
  // prctl(PR_SET_PDEATHSIG, SIGKILL), thus preventing a race condition where
  // the parent is killed before that call was made.
  WaitPipe(pipe_from_child);

  PRINT_DEBUG("done manipulating pipes");

  return child_pid;
}

static int64_t ReadCgroupsMemoryPeak(
    const std::vector<std::string>& cgroups_dirs) {
  int64_t max_value = -1;
  for (const std::string& dir : cgroups_dirs) {
    for (const char* fname : {"/memory.peak", "/memory.max_usage_in_bytes"}) {
      int64_t value = -1;
      std::string path = dir + fname;
      FILE* f = fopen(path.c_str(), "r");
      if (f != nullptr) {
        if (fscanf(f, "%" SCNd64, &value) == 1) {
          max_value = std::max(value, max_value);
        }
        fclose(f);
      }
    }
  }
  return max_value;
}

static int WaitForPid1(const pid_t child_pid) {
  // Wait for the child to exit, obtaining usage information. Restart in the
  // case of a signal interrupting us.
  int child_status;
  struct rusage child_rusage;
  while (true) {
    const int ret = wait4(child_pid, &child_status, 0, &child_rusage);
    if (ret > 0) {
      break;
    }

    // We've been handed off to a reaper process and should die.
    if (getppid() != initial_ppid) {
      break;
    }

    if (errno == EINTR) {
      continue;
    }

    DIE("wait4");
  }

  // If we're supposed to write stats to a file, do so now.
  if (!opt.stats_path.empty()) {
    int64_t cgroups_memory_peak = ReadCgroupsMemoryPeak(opt.cgroups_dirs);
    if (cgroups_memory_peak > 0) {
      child_rusage.ru_maxrss = cgroups_memory_peak / 1024;
    }
    WriteStatsToFile(&child_rusage, opt.stats_path);
  }

  // We want to exit in the same manner as the child.
  if (WIFSIGNALED(child_status)) {
    const int signal = WTERMSIG(child_status);
    PRINT_DEBUG("child exited due to receiving signal: %s", strsignal(signal));
    return 128 + signal;
  }

  const int exit_code = WEXITSTATUS(child_status);
  PRINT_DEBUG("child exited normally with code %d", exit_code);
  return exit_code;
}

int main(int argc, char *argv[]) {
  // Ask the kernel to kill us with SIGKILL if our parent dies.
  if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) {
    DIE("prctl");
  }

  // Parse our command-line options.
  ParseOptions(argc, argv);

  // Open the file PRINT_DEBUG writes to.
  // Must happen early enough so we don't lose any debugging output.
  if (!opt.debug_path.empty()) {
    global_debug = fopen(opt.debug_path.c_str(), "w");
    if (!global_debug) {
      DIE("fopen(%s)", opt.debug_path.c_str());
    }
  }

  // Start with default signal actions and a clear signal mask.
  ClearSignalMask();

  // Ignore SIGTTIN and SIGTTOU, as we hand off the terminal to the child in
  // SpawnChild.
  IgnoreSignal(SIGTTIN);
  IgnoreSignal(SIGTTOU);

  // Remember the parent pid so we can exit if the parent has exited.
  // Doing this before prctl(PR_SET_PDEATHDIG, 0) ensures no race condition.
  initial_ppid = getppid();

  if (opt.persistent_process) {
    if (prctl(PR_SET_PDEATHSIG, 0) < 0) {
      DIE("prctl");
    }
  }

  // Redirect output as requested.
  Redirect(opt.stdout_path, STDOUT_FILENO);
  Redirect(opt.stderr_path, STDERR_FILENO);

  // Set up two globals used by the child process.
  global_outer_uid = getuid();
  global_outer_gid = getgid();

  // Ensure we don't pass on any FDs from our parent to our child other than
  // stdin, stdout, stderr and global_debug.
  CloseFds();

  // Spawn the child that will fork the sandboxed program with fresh
  // namespaces etc.
  const pid_t child_pid = SpawnPid1();

  // Let the signal handlers installed below know the PID of the child.
  global_child_pid.store(child_pid, std::memory_order_relaxed);

  // If a kill delay has been configured, let the signal handlers installed
  // below know that it needs to be respected.
  if (opt.kill_delay_secs > 0) {
    global_need_polite_sigterm.store(1, std::memory_order_relaxed);
  }

  // OnTimeoutOrTerm, which is used for other signals below, assumes that it
  // handles SIGALRM. We also explicitly invoke it after the timeout using
  // alarm(2).
  InstallSignalHandler(SIGALRM, OnTimeoutOrTerm);

  // If requested, arrange for the child to be killed (optionally after being
  // asked politely to terminate) once the timeout expires.
  //
  // Note that it's important to set this up before support for SIGTERM and
  // SIGINT. Otherwise one of those signals could arrive before we get here,
  // and then we would reset its opt.kill_delay_secs interval timer.
  if (opt.timeout_secs > 0) {
    alarm(opt.timeout_secs);
  }

  // Also ask/tell the child to quit on SIGTERM, and optionally for SIGINT
  // too.
  InstallSignalHandler(SIGTERM, OnTimeoutOrTerm);
  if (opt.sigint_sends_sigterm) {
    InstallSignalHandler(SIGINT, OnTimeoutOrTerm);
  }

  // Wait for the child to exit, returning an appropriate status.
  return WaitForPid1(child_pid);
}
