// 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/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/process/process.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 <pi-arc>/art/build/art.go
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";

// 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_dalvik_cache_directory{kArtDalvikCacheDirectory};
  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, AndroidSdkVersion sdk_version) {
  auto art_paths = std::make_unique<ArtContainerPaths>();

  // Make sure the data directory exits.
  CHECK(base::PathExists(art_paths->art_dalvik_cache_directory));

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

// 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,
                           AndroidSdkVersion sdk_version)
    : mounter_(mounter),
      art_paths_(std::move(art_paths)),
      sdk_version_(sdk_version) {}

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_dalvik_cache_directory.DirName(),
      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 dalvik-cache directory.
  if (!DeleteFilesInDir(art_paths_->art_dalvik_cache_directory.Append(isa))) {
    LOG(ERROR) << "Failed to delete existing images in "
               << kArtDalvikCacheDirectory;
    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;
  }

  const base::FilePath art_container_data_directory =
      base::FilePath(kArtDalvikCacheDirectory).DirName();
  ret = minijail_bind(art_jail.get(),
                      art_container_data_directory.value().c_str(), "/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;
  }

  std::string output_arg;
  switch (sdk_version_) {
    case AndroidSdkVersion::UNKNOWN:
      LOG(ERROR) << "Unknown Android sdk version.";
      return false;
    // For Android P, use --output-image-directory.
    default:
      output_arg = "--output-image-directory=/data/dalvik-cache/" + isa;
      break;
  }

  std::string isa_arg = "--instruction-set=" + isa;

  int32_t offset = ChooseRelocationOffsetDelta(
      kArtBaseAddressMinDelta, kArtBaseAddressMaxDelta, offset_seed);
  std::string base_offset_arg = "--base-offset-delta=" + std::to_string(offset);

  const char* argv[] = {kPatchOat,
                        "--input-image-location=/system/framework/boot.art",
                        output_arg.c_str(),
                        isa_arg.c_str(),
                        base_offset_arg.c_str(),
                        "--dump-timings",
                        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";
  }
  LOG(INFO) << "Running " << kPatchOat << " for isa " << isa;
  // 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
