// Copyright (c) 2012 The Chromium OS 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 "debugd/src/sandboxed_process.h"

#include <inttypes.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <base/strings/stringprintf.h>

namespace debugd {

namespace {

const size_t kMaxWaitAttempts = 3;
const unsigned int kDelayUSec = 1000;

const char kMiniJail[] = "/sbin/minijail0";

// waitpid(2) with a timeout of kMaxWaitAttempts * kDelayUSec.
bool waitpid_awhile(pid_t pid) {
  DCHECK_GT(pid, 0);
  for (size_t attempt = 0; attempt < kMaxWaitAttempts; ++attempt) {
    pid_t res = waitpid(pid, nullptr, WNOHANG);
    if (res > 0) {
      return true;
    }
    if (res < 0) {
      PLOG(ERROR) << "waitpid(" << pid << ") failed";
      return false;
    }
    usleep(kDelayUSec);
  }
  return false;
}

}  // namespace

const char SandboxedProcess::kDefaultUser[] = "debugd";
const char SandboxedProcess::kDefaultGroup[] = "debugd";

SandboxedProcess::SandboxedProcess()
    : sandboxing_(true),
      access_root_mount_ns_(false),
      set_capabilities_(false),
      inherit_usergroups_(false),
      user_(kDefaultUser),
      group_(kDefaultGroup) {
}

// static
bool SandboxedProcess::GetHelperPath(const std::string& relative_path,
                                     std::string* full_path) {
  // This environment variable controls the root directory for debugd helpers,
  // which lets people develop helpers even when verified boot is on.
  const char* helpers_dir = getenv("DEBUGD_HELPERS");
  std::string path = base::StringPrintf(
      "%s/%s",
      helpers_dir ? helpers_dir : "/usr/libexec/debugd/helpers",
      relative_path.c_str());

  if (path.length() > PATH_MAX)
    return false;

  *full_path = path;
  return true;
}

bool SandboxedProcess::Init() {
  if (sandboxing_ && (user_.empty() || group_.empty())) {
      // Cannot sandbox without user/group.
      return false;
  }

  if (set_capabilities_ && (!sandboxing_ || user_ == "root")) {
      // Restricting capabilities requires dropping root.
      return false;
  }

  AddArg(kMiniJail);
  // Enter a new mount namespace. This is done for every process to avoid
  // affecting the original mount namespace.
  AddArg("-v");

  if (sandboxing_) {
    if (user_ != "root") {
      AddArg("-u");
      AddArg(user_);
    }
    if (group_ != "root") {
      AddArg("-g");
      AddArg(group_);
    }
    if (inherit_usergroups_) {
      AddArg("-G");
    }
    if (set_capabilities_) {
      AddStringOption("-c",
                      base::StringPrintf("0x%" PRIx64, capabilities_mask_));
    }
  }

  if (access_root_mount_ns_) {
    // Enter root mount namespace.
    AddStringOption("-V", "/proc/1/ns/mnt");
  }

  if (!seccomp_filter_policy_file_.empty()) {
    AddStringOption("-S", seccomp_filter_policy_file_);

    // Whenever we use a seccomp filter, we want no-new-privs so we can apply
    // the policy after dropping other privs.
    AddArg("-n");
  }

  AddArg("--");

  return true;
}

void SandboxedProcess::DisableSandbox() {
  sandboxing_ = false;
}

void SandboxedProcess::SandboxAs(const std::string& user,
                                 const std::string& group) {
  sandboxing_ = true;
  user_ = user;
  group_ = group;
}

void SandboxedProcess::InheritUsergroups() {
  inherit_usergroups_ = true;
}

void SandboxedProcess::SetCapabilities(uint64_t capabilities_mask) {
  set_capabilities_ = true;
  capabilities_mask_ = capabilities_mask;
}

void SandboxedProcess::SetSeccompFilterPolicyFile(const std::string& path) {
  seccomp_filter_policy_file_ = path;
}

void SandboxedProcess::AllowAccessRootMountNamespace() {
  access_root_mount_ns_ = true;
}

bool SandboxedProcess::KillProcessGroup() {
  pid_t minijail_pid = pid();
  if (minijail_pid == 0) {
    LOG(ERROR) << "Process is not running";
    return false;
  }

  // Minijail sets its process group ID equal to its PID,
  // so we can use pid() as PGID. Check that's still the case.
  pid_t pgid = getpgid(minijail_pid);
  if (pgid < 0) {
    PLOG(ERROR) << "getpgid(minijail_pid) failed";
    return false;
  }
  if (pgid != minijail_pid) {
    LOG(ERROR) << "Minijail PGID " << pgid << " is different from PID "
               << minijail_pid;
    return false;
  }

  // Attempt to kill minijail gracefully with SIGINT and then SIGTERM.
  // Note: we fall through to SIGKILLing the process group below even if this
  // succeeds to ensure all descendents have been killed.
  bool minijail_reaped = false;
  for (auto sig : {SIGINT, SIGTERM}) {
    if (kill(minijail_pid, sig) != 0) {
      // ESRCH means the process already exited.
      if (errno != ESRCH) {
        PLOG(WARNING) << "failed to kill " << minijail_pid
                      << " with signal " << sig;
      }
      break;
    }
    if (waitpid_awhile(minijail_pid)) {
      minijail_reaped = true;
      break;
    }
  }

  // kill(-pgid) kills every process with process group ID |pgid|.
  if (kill(-pgid, SIGKILL) != 0) {
    // ESRCH means the graceful exit above caught everything.
    if (errno != ESRCH) {
      PLOG(ERROR) << "kill(-pgid, SIGKILL) failed";
      return false;
    }
  }

  // If kill(2) succeeded, we release the PID.
  UpdatePid(0);

  // We only expect to reap one process, the Minijail process.
  // If the jailed process dies first, Minijail or init will reap it.
  // If the Minijail process dies first, we will reap it. The jailed process
  // will then be reaped by init.
  if (!minijail_reaped && !waitpid_awhile(minijail_pid)) {
    LOG(ERROR) << "Process " << minijail_pid << " did not terminate";
    return false;
  }

  return true;
}

}  // namespace debugd
