// Copyright 2012 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <base/command_line.h>
#include <base/logging.h>
#include <brillo/daemons/dbus_daemon.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <chromeos/dbus/service_constants.h>
#include <chromeos/libminijail.h>
#include <chromeos/scoped_minijail.h>

#include "debugd/src/debugd_dbus_adaptor.h"

namespace {

// For TPM 1.2 only: Directory to mount for access to tcsd socket.
constexpr char kTcsdDir[] = "/run/tcsd";

// Minijail APIs tend to return the errno value directly, so pull that out and
// then return success based on it.
static inline bool mj_call(int ret) {
  errno = -ret;
  return errno == 0;
}

// @brief Enter a VFS namespace.
//
// We don't want anyone other than our descendants to see our tmpfs.
void enter_vfs_namespace() {
  ScopedMinijail j(minijail_new());

  // Create a minimalistic mount namespace with just the bare minimum required.
  minijail_namespace_vfs(j.get());
  PCHECK(mj_call(minijail_enter_pivot_root(j.get(), "/mnt/empty")));
  PCHECK(mj_call(minijail_bind(j.get(), "/", "/", 0)));
  PCHECK(mj_call(minijail_mount_with_data(j.get(), "none", "/proc", "proc",
                                          MS_NOSUID | MS_NOEXEC | MS_NODEV,
                                          nullptr)));
  PCHECK(mj_call(minijail_bind(j.get(), "/var", "/var", 1)));

  // Hack a path for vpd until it can migrate to /var.
  // https://crbug.com/876838
  PCHECK(mj_call(minijail_mount_with_data(j.get(), "tmpfs", "/mnt", "tmpfs",
                                          MS_NOSUID | MS_NOEXEC | MS_NODEV,
                                          "mode=0755,size=10M")));
  const char kVpdPath[] = "/mnt/stateful_partition/unencrypted/cache/vpd";
  PCHECK(mj_call(minijail_bind(j.get(), kVpdPath, kVpdPath, 1)));

  // debugd needs access to the stateful swap directory.
  const base::FilePath kSwapWbDir(
      "/mnt/stateful_partition/unencrypted/userspace_swap.tmp");
  if (!base::PathExists(kSwapWbDir)) {
    base::File::Error error;
    if (!base::CreateDirectoryAndGetError(kSwapWbDir, &error)) {
      LOG(FATAL) << "Unable to create " << kSwapWbDir << ":"
                 << base::File::ErrorToString(error);
    }
  }
  PCHECK(mj_call(minijail_bind(j.get(), kSwapWbDir.MaybeAsASCII().c_str(),
                               kSwapWbDir.MaybeAsASCII().c_str(), 1)));

  minijail_remount_mode(j.get(), MS_SLAVE);

  PCHECK(mj_call(minijail_mount_with_data(j.get(), "tmpfs", "/run", "tmpfs",
                                          MS_NOSUID | MS_NOEXEC | MS_NODEV,
                                          nullptr)));

  PCHECK(mj_call(minijail_mount(j.get(), "/run/daemon-store/debugd",
                                "/run/daemon-store/debugd", "none",
                                MS_BIND | MS_REC)));

  // Mount /run/debugd for a shared place for runtime data.
  PCHECK(mj_call(minijail_bind(j.get(), "/run/debugd", "/run/debugd", 1)));

  // Mount /run/dbus to be able to communicate with D-Bus.
  PCHECK(mj_call(minijail_bind(j.get(), "/run/dbus", "/run/dbus", 0)));

  // Mount /tmp, /run/cups, and /run/ippusb to be able to communicate with CUPS.
  // /tmp must be at least 3 * kernel partition size plus a little extra. This
  // is required by make_dev_ssd.sh, which is called from debugd through
  // dev_features_rootfs_verification.
  //
  // The script reads out the old kernel partition as a blob, repacks it (which
  // often leads to a smaller blob), then copies the old blob to a new blob and
  // overwrites the repacked kernel onto the new blob.
  minijail_mount_tmp_size(j.get(), 100 * 1024 * 1024);
  PCHECK(mj_call(minijail_bind(j.get(), "/run/cups", "/run/cups", 0)));
  // Mount /run/ippusb to be able to communicate with CUPS.
  PCHECK(mj_call(minijail_bind(j.get(), "/run/ippusb", "/run/ippusb", 0)));

  // Mount writable debug directories for cups, ippusb, and lorgnette for use
  // with printscan_tool.
  PCHECK(
      mj_call(minijail_bind(j.get(), "/run/cups/debug", "/run/cups/debug", 1)));
  PCHECK(mj_call(
      minijail_bind(j.get(), "/run/ippusb/debug", "/run/ippusb/debug", 1)));
  PCHECK(mj_call(minijail_bind(j.get(), "/run/lorgnette/debug",
                               "/run/lorgnette/debug", 1)));

  // In case we start before avahi-daemon, make sure the path exists.
  mkdir("/var/run/avahi-daemon", 0755);
  // Mount /run/avahi-daemon in order to perform mdns name resolution.
  PCHECK(mj_call(
      minijail_bind(j.get(), "/run/avahi-daemon", "/run/avahi-daemon", 0)));

  // Since shill provides network resolution settings, bind mount it.
  // In case we start before shill, make sure the path exists.
  // TODO(259354228): Remove once resolv.conf migration to dns-proxy is done.
  mkdir("/run/shill", 0755);
  PCHECK(mj_call(minijail_bind(j.get(), "/run/shill", "/run/shill", 0)));

  // Since dns-proxy provides network resolution settings, bind mount it.
  // Path is expected to always exists before as it is created through
  // tmpfiles.d.
  PCHECK(
      mj_call(minijail_bind(j.get(), "/run/dns-proxy", "/run/dns-proxy", 0)));

  // Bind mount /run/lockbox and /var/lib/devicesettings to be able to read
  // policy files and check device policies.
  // In case we start before, make sure the path exists.
  mkdir("/run/lockbox", 0755);
  PCHECK(mj_call(minijail_bind(j.get(), "/run/lockbox", "/run/lockbox", 0)));
  // In case we start before, make sure the path exists.
  mkdir("/var/lib/devicesettings", 0755);
  PCHECK(mj_call(minijail_bind(j.get(), "/var/lib/devicesettings",
                               "/var/lib/devicesettings", 0)));

  // Mount /dev to be able to inspect devices.
  PCHECK(mj_call(minijail_mount_with_data(j.get(), "/dev", "/dev", "bind",
                                          MS_BIND | MS_REC, nullptr)));

  // Mount /sys to access some logs.
  PCHECK(mj_call(minijail_mount_with_data(j.get(), "/sys", "/sys", "bind",
                                          MS_BIND | MS_REC, nullptr)));

  // Mount /run/chromeos-config/v1 to access chromeos-config.
  PCHECK(mj_call(minijail_bind(j.get(), "/run/chromeos-config/v1",
                               "/run/chromeos-config/v1", 0)));

  // Mount /run/lock so that lock file for crossystem is shared.
  PCHECK(mj_call(minijail_bind(j.get(), "/run/lock", "/run/lock", 1)));

  if (USE_TPM) {
    // For TPM 1.2 only: Enable utilities that communicate with TPM via tcsd -
    // mount directory containing tcsd socket.
    mkdir(kTcsdDir, 0755);
    PCHECK(mj_call(minijail_bind(j.get(), kTcsdDir, kTcsdDir, 0)));
  }

  minijail_enter(j.get());
}

class Daemon : public brillo::DBusServiceDaemon {
 public:
  explicit Daemon(const bool perf_logging)
      : DBusServiceDaemon(debugd::kDebugdServiceName),
        perf_logging_(perf_logging) {}
  Daemon(const Daemon&) = delete;
  Daemon& operator=(const Daemon&) = delete;

 protected:
  void RegisterDBusObjectsAsync(
      brillo::dbus_utils::AsyncEventSequencer* sequencer) override {
    adaptor_.reset(new debugd::DebugdDBusAdaptor(bus_, perf_logging_));
    adaptor_->RegisterAsync(
        sequencer->GetHandler("RegisterAsync() failed.", true));
  }

 private:
  std::unique_ptr<debugd::DebugdDBusAdaptor> adaptor_;
  bool perf_logging_;
};

}  // namespace

int main(int argc, char* argv[]) {
  DEFINE_bool(perf_logging, false,
              "Record and locally log the performance of all LogTool sub-tasks "
              "within the feedback log collection function.")
      brillo::FlagHelper::Init(argc, argv, "CrOS debug daemon");
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);

  enter_vfs_namespace();
  Daemon(FLAGS_perf_logging).Run();
  return 0;
}
