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