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

// This code is taken from debugd since we do not want it in brillo for reasons
// that are alluded to in crbug.com/1085464

#include "diagnostics/cros_healthd/process/sandboxed_process.h"

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

#include <string>
#include <vector>

#include <base/strings/stringprintf.h>

namespace diagnostics {

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[] = "cros_healthd";
const char SandboxedProcess::kDefaultGroup[] = "cros_healthd";

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

bool SandboxedProcess::Init(
    const std::vector<std::string>& minijail_extra_args) {
  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");
  }

  for (const auto& arg : minijail_extra_args)
    AddArg(arg);

  AddArg("--");

  return true;
}

bool SandboxedProcess::Init() {
  return Init({});
}

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 diagnostics
