// Copyright 2016 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/oom_adj_tool.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#include <memory>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <brillo/userdb_utils.h>

#include "debugd/src/process_with_output.h"

namespace debugd {

namespace {

constexpr char kProcfsDirFormat[] = "/proc/%d";
constexpr char kOomScoreAdjFileFormat[] = "/proc/%d/oom_score_adj";
constexpr char kUidMapFileFormat[] = "/proc/%d/uid_map";

// Though uid might be an unsigned int, some system call like setreuid() still
// accepts uid_t as -1 as a special invalid value. I followed the tradition in
// this file.
constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);

uid_t GetUidForUsername(const std::string& user_name) {
  uid_t uid;
  return brillo::userdb::GetUserInfo(user_name, &uid, nullptr) ? uid
                                                               : kInvalidUid;
}

bool IsValidUid(const uid_t uid) {
  return uid != kInvalidUid;
}

// Print and collect errors.
void PrintAndAppendError(std::string* errors, const std::string& new_error) {
  LOG(WARNING) << new_error;
  *errors += new_error + "\n";
}

// A helper class to get process attributes like process owner, etc.
class ProcessHandler {
 public:
  explicit ProcessHandler(const pid_t pid);
  ~ProcessHandler() = default;

  // Get UID of the process |pid_|.
  uid_t GetProcessOwnerUid(std::string* errors);

  // Get UID of root inside the user namespace |pid_| is in.
  uid_t GetUserNamespaceRootUid(std::string* errors);

 private:
  const pid_t pid_;
};

ProcessHandler::ProcessHandler(const pid_t pid) : pid_(pid) {}

uid_t ProcessHandler::GetProcessOwnerUid(std::string* errors) {
  std::string procfs_entry = base::StringPrintf(kProcfsDirFormat, pid_);
  base::ScopedFD procfs_fd(open(procfs_entry.c_str(), O_RDONLY | O_DIRECTORY));
  if (!procfs_fd.is_valid()) {
    PrintAndAppendError(
        errors,
        base::StringPrintf("Failed to open procfs entry of process %d", pid_));
    return kInvalidUid;
  }

  struct stat statbuf;
  if (fstat(procfs_fd.get(), &statbuf) < 0) {
    PrintAndAppendError(
        errors, base::StringPrintf("Failed to get uid of process %d", pid_));
    return kInvalidUid;
  }

  return statbuf.st_uid;
}

uid_t ProcessHandler::GetUserNamespaceRootUid(std::string* errors) {
  base::FilePath uid_map_file(base::StringPrintf(kUidMapFileFormat, pid_));
  base::ScopedFILE uid_file(base::OpenFile(uid_map_file, "r"));
  if (!uid_file) {
    PrintAndAppendError(
        errors,
        base::StringPrintf("Failed to open uid map file %s for process %d",
                           uid_map_file.value().c_str(), pid_));
    return kInvalidUid;
  }

  uid_t start, map;
  // Each line in the uid_map file specifies a 1-to-1 mapping of a range
  // of contiguous user IDs between two user namespaces. The first two numbers
  // specify the starting user ID in each of the two user namespaces. The
  // third number specifies the length of the mapped range.
  // Assume root user in the user namespace of |pid_| is mapped to the calling
  // user namespace. If not it returns kInvalidUid.
  while (fscanf(uid_file.get(), "%d%d%*d", &start, &map) == 2) {
    // Returns mapping of UID 0 = root.
    if (start == 0)
      return map;
  }
  return kInvalidUid;
}

// Batch set oom_score_adj for a list of processes. Only Chrome tabs and
// Android apps are valid target.
class OomScoreSetter {
 public:
  OomScoreSetter()
      : chronos_uid_(GetUidForUsername("chronos")),
        android_root_uid_(GetUidForUsername("android-root")) {}
  ~OomScoreSetter() = default;

  // Entry point.
  std::string Set(const std::map<pid_t, int32_t>& scores);

 private:
  // Sets oom_score_adj for one process.
  void SetOne(const pid_t pid, const int32_t score, std::string* errors);

  // Whether it's valid to alter OOM score of the given process |pid_|.
  bool IsValidOwner(const pid_t pid, std::string* errors);

  const uid_t chronos_uid_;
  const uid_t android_root_uid_;
};

std::string OomScoreSetter::Set(const std::map<pid_t, int32_t>& scores) {
  VLOG(2) << "UID of chronos: " << chronos_uid_;
  VLOG(2) << "UID of android-root: " << android_root_uid_;

  std::string errors;
  for (const auto& entry : scores) {
    const pid_t& pid = entry.first;
    const int32_t& score = entry.second;
    VLOG(2) << "Setting OOM score " << score << " for process " << pid;

    SetOne(pid, score, &errors);
  }
  return errors;
}

void OomScoreSetter::SetOne(const pid_t pid,
                            const int32_t score,
                            std::string* errors) {
  if (!IsValidOwner(pid, errors)) {
    PrintAndAppendError(
        errors,
        base::StringPrintf("Invalid pid %d, operation not allowed", pid));
    return;
  }

  std::string score_str = std::to_string(score);
  const size_t len = score_str.length();
  base::FilePath oom_file(base::StringPrintf(kOomScoreAdjFileFormat, pid));
  ssize_t bytes_written = base::WriteFile(oom_file, score_str.c_str(), len);

  std::string write_error;
  if (bytes_written < 0) {
    write_error = strerror(errno);
  } else if ((size_t)bytes_written != len) {
    write_error = base::StringPrintf("%zd instead of %zu bytes written",
                                     bytes_written, len);
  }

  if (!write_error.empty()) {
    PrintAndAppendError(
        errors,
        base::StringPrintf("Write %d to %s failed: %s", score,
                           oom_file.value().c_str(), write_error.c_str()));
  }
}

// Returns true if
// 1. The process is owned by "chronos", or
// 2. The process is created in a user namespace where root is "android-root".
bool OomScoreSetter::IsValidOwner(const pid_t pid, std::string* errors) {
  ProcessHandler handler(pid);

  uid_t process_owner_uid = handler.GetProcessOwnerUid(errors);
  VLOG(2) << "Owner of " << pid << ": " << process_owner_uid;
  if (IsValidUid(process_owner_uid) && process_owner_uid == chronos_uid_)
    return true;

  uid_t namespace_root_uid = handler.GetUserNamespaceRootUid(errors);
  VLOG(2) << "Root of the user namespace " << pid
          << " is in: " << namespace_root_uid;
  if (IsValidUid(namespace_root_uid) && namespace_root_uid == android_root_uid_)
    return true;

  return false;
}

}  // namespace

std::string OomAdjTool::Set(const std::map<pid_t, int32_t>& scores) {
  OomScoreSetter setter;
  return setter.Set(scores);
}

}  // namespace debugd
