// Copyright 2017 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 "arc/setup/art_container.h"

#include <stdlib.h>
#include <sys/mount.h>
#include <unistd.h>

#include <memory>
#include <random>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/posix/eintr_wrapper.h>
#include <base/process/process.h>
#include <base/strings/stringprintf.h>
#include <chromeos/libminijail.h>
#include <scoped_minijail.h>

namespace arc {

namespace {

constexpr char kAndroidRootfs[] =
    "/opt/google/containers/arc-art/mountpoints/container-root";
constexpr char kAndroidVendor[] =
    "/opt/google/containers/arc-art/mountpoints/vendor";
constexpr char kLibLogStderrName[] = "liblog_stderr.so";

// Variables defined in Android <nyc-mr1-arc>/art/build/Android.common_build.mk
constexpr uint32_t kArtBaseAddressMaxDelta = 0x1000000;
constexpr uint32_t kArtBaseAddressMinDelta = -0x1000000;

constexpr char kArtDevRootfsDirectory[] =
    "/opt/google/containers/arc-art/mountpoints/dev-rootfs";
constexpr char kArtDevRootfsImage[] =
    "/opt/google/containers/arc-art/dev-rootfs.squashfs";
constexpr char kArtRootfsDirectory[] =
    "/opt/google/containers/arc-art/mountpoints/container-root";
// TODO(xzhou): Use sysconf(_SC_PAGESIZE).
constexpr uint32_t kPageSize = 4096;
constexpr char kPatchOat[] = "/system/bin/patchoat";
constexpr char kPidFile[] = "/run/patchoat.pid";
constexpr char kSystemImage[] = "/opt/google/containers/android/system.raw.img";
constexpr char kVendorImage[] = "/opt/google/containers/android/vendor.raw.img";
constexpr uid_t kHostRootUid = 0;
constexpr gid_t kHostRootGid = 0;

// Creates kArtContainerDataDirectory directory if not exists.
bool CreateArtContainerDataDirectory(
    base::FilePath art_dalvik_cache_directory) {
  for (const std::string& isa : ArtContainer::GetIsas()) {
    base::FilePath isa_directory = art_dalvik_cache_directory.Append(isa);
    if (!InstallDirectory(0755, kHostRootUid, kHostRootGid, isa_directory)) {
      PLOG(ERROR) << "Failed to create art container data dir: "
                  << isa_directory.value();
      return false;
    }
  }
  return true;
}

// Ported from Andriod nyc
template <typename T>
struct Identity {
  using type = T;
};

#define CHECK_CONSTEXPR(x, out, dummy) \
  (UNLIKELY(!(x))) ? (LOG(ERROR) << "Check failed: " << #x out, dummy):

#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)

template <typename T>
static constexpr int CLZ(T x) {
  static_assert(std::is_integral<T>::value, "T must be integral");
  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
  static_assert(sizeof(T) <= sizeof(long long),  // NOLINT [runtime/int] [4]
                "T too large, must be smaller than long long");
  return DCHECK_CONSTEXPR(x != 0, "x must not be zero",
                          T(0))(sizeof(T) == sizeof(uint32_t))
             ? __builtin_clz(x)
             : __builtin_clzll(x);
}

template <typename T>
static constexpr bool IsPowerOfTwo(T x) {
  static_assert(std::is_integral<T>::value, "T must be integral");
  return (x & (x - 1)) == 0;
}

// For rounding integers.
template <typename T>
static constexpr T RoundDown(T x, typename Identity<T>::type n) {
  return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n);
}

template <typename T>
static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
  return RoundDown(x + n - 1, n);
}

template <int n, typename T>
static constexpr bool IsAligned(T x) {
  static_assert((n & (n - 1)) == 0, "n is not a power of two");
  return (x & (n - 1)) == 0;
}

#define CHECK_ALIGNED(value, alignment) \
  CHECK(IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)

template <typename T>
T GetRandomNumber(T min, T max) {
  CHECK_LT(min, max);
  std::uniform_int_distribution<T> dist(min, max);
  std::random_device rng;
  return dist(rng);
}

int32_t GetOffset(int32_t min, int32_t max, uint64_t offset_seed) {
  CHECK_LT(min, max);
  const uint32_t range = max - min;
  const uint32_t offset = offset_seed % range;
  CHECK_LT(offset, range);
  return min + offset;
}

int32_t ChooseRelocationOffsetDelta(int32_t min_delta,
                                    int32_t max_delta,
                                    uint64_t offset_seed) {
  CHECK_ALIGNED(min_delta, kPageSize);
  CHECK_ALIGNED(max_delta, kPageSize);
  CHECK_LT(min_delta, max_delta);

  int32_t r = offset_seed ? GetOffset(min_delta, max_delta, offset_seed)
                          : GetRandomNumber(min_delta, max_delta);
  if (r % 2 == 0) {
    r = RoundUp(r, kPageSize);
  } else {
    r = RoundDown(r, kPageSize);
  }
  CHECK_LE(min_delta, r);
  CHECK_GE(max_delta, r);
  CHECK_ALIGNED(r, kPageSize);
  return r;
}

}  // namespace

struct ArtContainerPaths {
  const base::FilePath art_data_directory{kArtContainerDataDirectory};
  const base::FilePath art_dev_rootfs_directory{kArtDevRootfsDirectory};
  const base::FilePath art_rootfs_directory{kArtRootfsDirectory};
  const base::FilePath vendor_directory{kAndroidVendor};
};

// static
std::unique_ptr<ArtContainer> ArtContainer::CreateContainer(
    ArcMounter* mounter) {
  auto art_paths = std::make_unique<ArtContainerPaths>();
  // Make sure the data directory exits.
  const base::FilePath art_dalvik_cache_dir =
      art_paths->art_data_directory.Append("dalvik-cache");
  if (!arc::CreateArtContainerDataDirectory(art_dalvik_cache_dir))
    return nullptr;

  return std::unique_ptr<ArtContainer>(
      new ArtContainer(mounter, std::move(art_paths)));
}

// static
bool ArtContainer::CreateArtContainerDataDirectory() {
  return arc::CreateArtContainerDataDirectory(
      ArtContainerPaths().art_data_directory.Append("dalvik-cache"));
}

// static
std::vector<std::string> ArtContainer::GetIsas() {
  std::vector<std::string> isas;
  for (const std::string& arch : {"arm", "arm64", "x86", "x86_64"}) {
    if (base::DirectoryExists(base::FilePath(kFrameworkPath).Append(arch)))
      isas.push_back(arch);
  }
  return isas;
}

ArtContainer::ArtContainer(ArcMounter* mounter,
                           std::unique_ptr<ArtContainerPaths> art_paths)
    : mounter_(mounter), art_paths_(std::move(art_paths)) {}

ArtContainer::~ArtContainer() = default;

bool ArtContainer::PatchImage(uint64_t offset_seed) {
  int pid = fork();
  if (pid == -1) {
    PLOG(ERROR) << "Failed to fork()";
    return false;
  }

  if (pid == 0) {
    // Avoid doing any cleanup in the child process. This avoids problems where
    // an atexit(3) handler (if any) that can modify global state (e.g. mounts)
    // is called before it is expected (i.e. when main() returns in the parent).
    _exit(PatchImageChild(offset_seed) ? EXIT_SUCCESS : EXIT_FAILURE);
  }

  base::Process process(pid);
  int exit_code = -1;
  if (!process.WaitForExit(&exit_code)) {
    PLOG(ERROR) << "Failed to wait for the ART container";
    return false;
  }
  if (exit_code != EXIT_SUCCESS) {
    LOG(ERROR) << "The ART container exited with non-zero code: " << exit_code;
    return false;
  }
  return true;
}

bool ArtContainer::PatchImageChild(uint64_t offset_seed) {
  {
    // Enter an intermediate mount namespace to avoid leaking mounts.
    ScopedMinijail art_jail(minijail_new());
    if (!art_jail)
      return false;
    minijail_namespace_vfs(art_jail.get());
    minijail_enter(art_jail.get());
  }

  // Mount rootfs, /vendor, /dev, /data for ART container.
  // TODO(xzhou): Simplify using minijail mounts.
  std::unique_ptr<ScopedMount> art_rootfs = ScopedMount::CreateScopedLoopMount(
      mounter_, kSystemImage, art_paths_->art_rootfs_directory,
      MS_RDONLY | MS_NOSUID | MS_NODEV);
  if (!art_rootfs)
    return false;
  std::unique_ptr<ScopedMount> loop_vendor = ScopedMount::CreateScopedLoopMount(
      mounter_, kVendorImage, art_paths_->vendor_directory,
      MS_RDONLY | MS_NOEXEC | MS_NOSUID);
  if (!loop_vendor)
    return false;
  std::unique_ptr<ScopedMount> art_vendor = ScopedMount::CreateScopedBindMount(
      mounter_, art_paths_->vendor_directory,
      art_paths_->art_rootfs_directory.Append("vendor"));
  if (!art_vendor)
    return false;
  // Patchoat did not map /dev/ashmem with PROT_EXEC and using MS_NOEXEC here.
  std::unique_ptr<ScopedMount> loop_dev = ScopedMount::CreateScopedLoopMount(
      mounter_, kArtDevRootfsImage, art_paths_->art_dev_rootfs_directory,
      MS_RDONLY | MS_NOEXEC | MS_NOSUID);
  if (!loop_dev)
    return false;
  std::unique_ptr<ScopedMount> art_dev = ScopedMount::CreateScopedBindMount(
      mounter_, art_paths_->art_dev_rootfs_directory.Append("dev"),
      art_paths_->art_rootfs_directory.Append("dev"));
  if (!art_dev)
    return false;
  // Bind mount /dev/ashmem from host to art container. The minor number of
  // ashmem is dynamic, we overwrite the one in art_dev.
  std::unique_ptr<ScopedMount> ashmem = ScopedMount::CreateScopedBindMount(
      mounter_, base::FilePath("/dev/ashmem"),
      art_paths_->art_rootfs_directory.Append("dev/ashmem"));
  if (!ashmem)
    return false;
  std::unique_ptr<ScopedMount> art_data = ScopedMount::CreateScopedBindMount(
      mounter_, art_paths_->art_data_directory,
      art_paths_->art_rootfs_directory.Append("data"));
  if (!art_data)
    return false;

  for (const std::string& isa : ArtContainer::GetIsas()) {
    if (!PatchImage(isa, offset_seed))
      return false;
  }
  return true;
}

bool ArtContainer::PatchImage(const std::string& isa, uint64_t offset_seed) {
  // Remove outdated files in kArtContainerDataDirectory.
  if (!DeleteFilesInDir(
          art_paths_->art_data_directory.Append("dalvik-cache").Append(isa))) {
    LOG(ERROR) << "Failed to delete existing images in "
               << kArtContainerDataDirectory;
    return false;
  }

  LOG(INFO) << "Running patchoat container...";
  // Start the patchoat container and relocate boot images.
  ScopedMinijail art_jail(minijail_new());
  minijail_no_new_privs(art_jail.get());
  int ret = minijail_enter_pivot_root(art_jail.get(), kAndroidRootfs);
  if (ret != 0) {
    LOG(ERROR) << "Can not set pivot root: " << strerror(-ret);
    return false;
  }
  minijail_namespace_vfs(art_jail.get());
  minijail_namespace_net(art_jail.get());
  minijail_namespace_pids(art_jail.get());
  minijail_skip_remount_private(art_jail.get());
  minijail_use_alt_syscall(art_jail.get(), "android");
  minijail_write_pid_file(art_jail.get(), kPidFile);

  // Preserve stdout and stderr.
  minijail_preserve_fd(art_jail.get(), STDOUT_FILENO, STDOUT_FILENO);
  minijail_preserve_fd(art_jail.get(), STDERR_FILENO, STDERR_FILENO);
  // Log to host stderr with priority 4, which is LOG_INFO and cannot
  // #include <syslog.h> due to name collisions with base/logging.h.
  minijail_log_to_fd(STDOUT_FILENO, 4);
  minijail_log_to_fd(STDERR_FILENO, 4);

  ret = minijail_mount_with_data(art_jail.get(), "proc", "/proc", "proc",
                                 MS_RDONLY | MS_NODEV | MS_NOEXEC, nullptr);
  // Set up private mount points.
  if (ret != 0) {
    LOG(ERROR) << "Failed to mount /proc: " << strerror(-ret);
    return false;
  }

  ret = minijail_bind(art_jail.get(), kArtContainerDataDirectory, "/data", 1);
  if (ret != 0) {
    LOG(ERROR) << "Failed to mount container data dir: " << strerror(-ret);
    return false;
  }

  ret = minijail_mount_with_data(art_jail.get(), "none", "/", "none",
                                 MS_REC | MS_PRIVATE, nullptr);
  if (ret != 0) {
    LOG(ERROR) << "Failed to mark PRIVATE recursively under pivot root "
               << strerror(-ret);
    return false;
  }
  int32_t offset = ChooseRelocationOffsetDelta(
      kArtBaseAddressMinDelta, kArtBaseAddressMaxDelta, offset_seed);
  std::string input_image_location_arg =
      "--input-image-location=/system/framework/boot.art";
  std::string output_image_file_arg = base::StringPrintf(
      "--output-image-file=/data/dalvik-cache/%s/system@framework@boot.art",
      isa.c_str());
  std::string instructionset_arg =
      base::StringPrintf("--instruction-set=%s", isa.c_str());
  std::string base_offset_arg =
      base::StringPrintf("--base-offset-delta=%d", offset);

  LOG(INFO) << "Relocate images: " << kPatchOat << " "
            << input_image_location_arg << " " << output_image_file_arg << " "
            << instructionset_arg << " "
            << "--base-offset-delta=0x******* ";

  const char* argv[] = {kPatchOat,
                        input_image_location_arg.c_str(),
                        output_image_file_arg.c_str(),
                        instructionset_arg.c_str(),
                        base_offset_arg.c_str(),
                        nullptr};
  // Set LD_PRELOAD to redirect all logd messages to stderr.
  base::FilePath liblog_stderr_path =
      art_paths_->art_rootfs_directory.Append("system/lib")
          .Append(kLibLogStderrName);
  // TODO(xzhou): Remove the check once the DSO is added to master-arc-dev.
  if (base::PathExists(liblog_stderr_path)) {
    LOG(INFO) << "Preloading " << kLibLogStderrName << " ...";
    // This is executed in a child process and does not change parent's env.
    setenv("LD_PRELOAD", kLibLogStderrName, 1 /* overwrite */);
  } else {
    LOG(ERROR) << "liblog_stderr does not exist, logd message not available";
  }
  // Need a android environment, no preload.
  // TODO(xzhou): Fix b/65159408 and run container as non root user.
  ret = minijail_run_no_preload(art_jail.get(), argv[0],
                                const_cast<char**>(argv));
  if (ret != 0) {
    LOG(ERROR) << "Failed to run minijail: " << strerror(-ret);
    return false;
  }

  do {
    ret = minijail_wait(art_jail.get());
  } while (ret == -EINTR);

  LOG(INFO) << "minijail wait return status: " << ret;

  return ret == EXIT_SUCCESS;
}

// static
int32_t ArtContainer::ChooseRelocationOffsetDeltaForTesting(
    int32_t min_delta, int32_t max_delta, uint64_t offset_seed) {
  return ChooseRelocationOffsetDelta(min_delta, max_delta, offset_seed);
}

}  // namespace arc
