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

#include "arc/adbd/adbd.h"

#include <fcntl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <linux/vm_sockets.h>  // NOLINT - needs to be after sys/socket.h

#include <memory>

#include <base/check_op.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/functional/bind.h>
#include <base/functional/callback_helpers.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/process/launch.h>
#include <base/strings/string_util.h>
#include <base/system/sys_info.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>
#include <base/values.h>

#include "arc/adbd/arcvm_sock_to_usb.h"
#include "arc/adbd/arcvm_usb_to_sock.h"

namespace adbd {
namespace {

constexpr uint16_t kAdbVsockPort = 5555;
constexpr char kRuntimePath[] = "/run/arc/adbd";
constexpr char kConfigFSPath[] = "/dev/config";
constexpr char kConfigPath[] = "/etc/arc/adbd.json";

// The shifted u/gid of the shell user, used by Android's adbd.
constexpr uid_t kShellUgid = 657360;

// The blob that is sent to FunctionFS to setup the adb gadget. This works for
// newer kernels (>=3.18). This and the following blobs were created by
// https://android.googlesource.com/platform/system/core/+/HEAD/adb/daemon/usb.cpp
constexpr const uint8_t kControlPayloadV2[] = {
    0x03, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
    0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x42, 0x01,
    0x01, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02,
    0x40, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x42, 0x01, 0x01,
    0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x82, 0x02, 0x00,
    0x02, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x42, 0x01, 0x01, 0x07,
    0x05, 0x01, 0x02, 0x00, 0x04, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00,
    0x07, 0x05, 0x82, 0x02, 0x00, 0x04, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

// The blob that is sent to FunctionFS to setup the adb gadget. This works
// for older kernels.
constexpr const uint8_t kControlPayloadV1[] = {
    0x01, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
    0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF,
    0x42, 0x01, 0x01, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07,
    0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02,
    0xFF, 0x42, 0x01, 0x01, 0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
    0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00};

// The blob that is sent to FunctionFS to setup the name of the gadget. It is
// "ADB Interface".
constexpr const uint8_t kControlStrings[] = {
    0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x41, 0x44, 0x42, 0x20,
    0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x00};

// Bind-mounts a file located in |source| to |target|. It also makes it be owned
// and only writable by Android shell.
bool BindMountFile(const base::FilePath& source, const base::FilePath& target) {
  if (!base::PathExists(target)) {
    base::ScopedFD target_file(
        HANDLE_EINTR(open(target.value().c_str(), O_WRONLY | O_CREAT, 0600)));
    if (!target_file.is_valid()) {
      PLOG(ERROR) << "Failed to touch " << target.value();
      return false;
    }
  }
  if (chown(source.value().c_str(), kShellUgid, kShellUgid) == -1) {
    PLOG(ERROR) << "Failed to chown " << source.value()
                << " to Android's shell user";
    return false;
  }
  if (mount(source.value().c_str(), target.value().c_str(), nullptr, MS_BIND,
            nullptr) == -1) {
    PLOG(ERROR) << "Failed to mount " << target.value();
    return false;
  }
  return true;
}

}  // namespace

bool CreatePipe(const base::FilePath& path) {
  // Create the FIFO at a temporary path. We will call rename(2) later to make
  // the whole operation atomic.
  const base::FilePath tmp_path = path.AddExtension(".tmp");
  if (unlink(tmp_path.value().c_str()) == -1 && errno != ENOENT) {
    PLOG(ERROR) << "Failed to remove stale FIFO at " << tmp_path.value();
    return false;
  }
  if (mkfifo(tmp_path.value().c_str(), 0600) == -1) {
    PLOG(ERROR) << "Failed to create FIFO at " << tmp_path.value();
    return false;
  }
  // base::Unretained is safe since the closure will be run before |tmp_path|
  // goes out of scope.
  base::ScopedClosureRunner unlink_fifo(base::BindOnce(
      base::IgnoreResult(&unlink), base::Unretained(tmp_path.value().c_str())));
  if (chown(tmp_path.value().c_str(), kShellUgid, kShellUgid) == -1) {
    PLOG(ERROR) << "Failed to chown FIFO at " << tmp_path.value()
                << " to Android's shell user";
    return false;
  }
  if (rename(tmp_path.value().c_str(), path.value().c_str()) == -1) {
    PLOG(ERROR) << "Failed to rename FIFO at " << tmp_path.value() << " to "
                << path.value();
    return false;
  }
  unlink_fifo.ReplaceClosure(base::DoNothing());
  return true;
}

bool GetConfiguration(AdbdConfiguration* config) {
  std::string config_json_data;
  if (!base::ReadFileToString(base::FilePath(kConfigPath), &config_json_data)) {
    PLOG(ERROR) << "Failed to read config from " << kConfigPath;
    return false;
  }

  auto config_root = base::JSONReader::ReadAndReturnValueWithError(
      config_json_data, base::JSON_PARSE_RFC);
  if (!config_root.has_value()) {
    LOG(ERROR) << "Failed to parse adb.json: " << config_root.error().message;
    return false;
  }
  if (!config_root->is_dict()) {
    LOG(ERROR) << "Failed to parse root dictionary from adb.json";
    return false;
  }
  const auto& config_root_dict = config_root->GetDict();

  const std::string* usb_product_id =
      config_root_dict.FindString("usbProductId");
  if (!usb_product_id) {
    LOG(ERROR) << "Failed to parse usbProductId";
    return false;
  }
  config->usb_product_id = *usb_product_id;

  auto dbc_supported = config_root_dict.FindBool("adbOverDbcSupport");
  if (dbc_supported) {
    config->dbc_supported = *dbc_supported;
  } else {
    config->dbc_supported = false;
  }

  if (config->dbc_supported) {
    const std::string* dbc_device_id =
        config_root_dict.FindString("pciBusDeviceId");
    if (!dbc_device_id) {
      LOG(ERROR) << "Failed to parse pciBusDeviceId for DbC";
      return false;
    }
    config->dbc_device_id = *dbc_device_id;
  }

  // kernelModules are optional.
  const base::Value::List* kernel_module_list =
      config_root_dict.FindList("kernelModules");
  if (kernel_module_list) {
    for (const auto& kernel_module_value : *kernel_module_list) {
      AdbdConfigurationKernelModule module;
      if (!kernel_module_value.is_dict()) {
        LOG(ERROR) << "kernelModules contains a non-dictionary";
        return false;
      }
      const auto& kernel_module_value_dict = kernel_module_value.GetDict();

      const std::string* module_name =
          kernel_module_value_dict.FindString("name");
      if (!module_name) {
        LOG(ERROR) << "Failed to parse kernelModules.name";
        return false;
      }
      module.name = *module_name;
      const base::Value::List* module_parameters =
          kernel_module_value_dict.FindList("parameters");
      if (module_parameters) {
        // Parameters are optional.
        for (const auto& parameter_value : *module_parameters) {
          if (!parameter_value.is_string()) {
            LOG(ERROR) << "kernelModules.parameters contains a non-string";
            return false;
          }
          module.parameters.emplace_back(parameter_value.GetString());
        }
      }
      config->kernel_modules.emplace_back(module);
    }
  }

  return true;
}

std::string GetUDCDriver() {
  base::FileEnumerator udc_enum(
      base::FilePath("/sys/class/udc/"), false /* recursive */,
      base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS);
  const base::FilePath name = udc_enum.Next();
  if (name.empty())
    return std::string();
  // We expect to only have one UDC driver in the system, so we can just return
  // the first file in the directory.
  return name.BaseName().value();
}

bool SetupConfigFS(const std::string& serialnumber,
                   const std::string& usb_product_id,
                   const std::string& usb_product_name) {
  const base::FilePath configfs_directory(kConfigFSPath);
  if (!base::CreateDirectory(configfs_directory)) {
    PLOG(ERROR) << "Failed to create " << configfs_directory.value();
    return false;
  }
  if (mount("configfs", configfs_directory.value().c_str(), "configfs",
            MS_NOEXEC | MS_NOSUID | MS_NODEV, nullptr) == -1) {
    PLOG(ERROR) << "Failed to mount configfs";
    return false;
  }

  // Setup the gadget.
  const base::FilePath gadget_path = configfs_directory.Append("usb_gadget/g1");
  if (!base::CreateDirectory(gadget_path.Append("functions/ffs.adb"))) {
    PLOG(ERROR) << "Failed to create ffs.adb directory";
    return false;
  }
  if (!base::CreateDirectory(gadget_path.Append("configs/b.1/strings/0x409"))) {
    PLOG(ERROR) << "Failed to create configs/b.1/strings directory";
    return false;
  }
  if (!base::CreateDirectory(gadget_path.Append("strings/0x409"))) {
    PLOG(ERROR) << "Failed to create config strings directory";
    return false;
  }
  const base::FilePath function_symlink_path =
      gadget_path.Append("configs/b.1/f1");
  if (!base::PathExists(function_symlink_path)) {
    if (!base::CreateSymbolicLink(gadget_path.Append("functions/ffs.adb"),
                                  function_symlink_path)) {
      PLOG(ERROR) << "Failed to create symbolic link";
      return false;
    }
  }
  // Argument-dependent lookup puts base::WriteFile into the candidates of
  // overload resolution although this is in the adbd namespace.
  // In libchrome r780000, the variant
  // base::WriteFile(const FilePath& filename, StringPiece data) will be added
  // which causes ambiguity to calling adbd::WriteFile.
  if (!base::WriteFile(gadget_path.Append("idVendor"), "0x18d1"))
    return false;
  if (!base::WriteFile(gadget_path.Append("idProduct"), usb_product_id))
    return false;
  if (!base::WriteFile(gadget_path.Append("strings/0x409/serialnumber"),
                       serialnumber)) {
    return false;
  }
  if (!base::WriteFile(gadget_path.Append("strings/0x409/manufacturer"),
                       "google"))
    return false;
  if (!base::WriteFile(gadget_path.Append("strings/0x409/product"),
                       usb_product_name))
    return false;
  if (!base::WriteFile(gadget_path.Append("configs/b.1/MaxPower"), "500"))
    return false;

  return true;
}

bool BindMountUsbBulkEndpoints() {
  const base::FilePath functionfs_path(kFunctionFSPath);
  const base::FilePath runtime_path(kRuntimePath);

  for (const auto& endpoint : {"ep1", "ep2"}) {
    if (!BindMountFile(functionfs_path.Append(endpoint),
                       runtime_path.Append(endpoint))) {
      return false;
    }
  }
  return true;
}

base::ScopedFD SetupFunctionFS(const std::string& udc_driver_name) {
  const base::FilePath functionfs_path(kFunctionFSPath);

  // Create the FunctionFS mount.
  if (!base::CreateDirectory(functionfs_path)) {
    PLOG(ERROR) << "Failed to create " << functionfs_path.value();
    return base::ScopedFD();
  }
  if (mount("adb", functionfs_path.value().c_str(), "functionfs",
            MS_NOEXEC | MS_NOSUID | MS_NODEV, nullptr) == -1) {
    PLOG(ERROR) << "Failed to mount functionfs";
    return base::ScopedFD();
  }

  // Send the configuration to the real control endpoint.
  base::ScopedFD control_file(HANDLE_EINTR(
      open(functionfs_path.Append("ep0").value().c_str(), O_WRONLY)));
  if (!control_file.is_valid()) {
    PLOG(ERROR) << "Failed to open control file";
    return base::ScopedFD();
  }
  if (!base::WriteFileDescriptor(control_file.get(), kControlPayloadV2)) {
    PLOG(WARNING) << "Failed to write the V2 control payload, "
                     "trying to write the V1 control payload";
    if (!base::WriteFileDescriptor(control_file.get(), kControlPayloadV1)) {
      PLOG(ERROR) << "Failed to write the V1 control payload";
      return base::ScopedFD();
    }
  }
  if (!base::WriteFileDescriptor(control_file.get(), kControlStrings)) {
    PLOG(ERROR) << "Failed to write the control strings";
    return base::ScopedFD();
  }
  if (!base::WriteFile(base::FilePath("/dev/config/usb_gadget/g1/UDC"),
                       udc_driver_name)) {
    return base::ScopedFD();
  }

  return control_file;
}

bool SetupKernelModules(
    const std::vector<AdbdConfigurationKernelModule>& kernel_modules) {
  for (const auto& kernel_module : kernel_modules) {
    std::vector<std::string> argv;
    argv.emplace_back("/usr/bin/modprobe");
    argv.emplace_back(kernel_module.name);
    argv.insert(std::end(argv), std::begin(kernel_module.parameters),
                std::end(kernel_module.parameters));
    base::Process process(base::LaunchProcess(argv, base::LaunchOptions()));
    if (!process.IsValid()) {
      PLOG(ERROR) << "Failed to invoke /usr/bin/modprobe "
                  << kernel_module.name;
      return false;
    }
    int exit_code = -1;
    if (!process.WaitForExit(&exit_code)) {
      PLOG(ERROR) << "Failed to wait for /usr/bin/modprobe "
                  << kernel_module.name;
      return false;
    }
    if (exit_code != 0) {
      LOG(ERROR) << "Invocation of /usr/bin/modprobe " << kernel_module.name
                 << " exited with non-zero code " << exit_code;
      return false;
    }
  }
  return true;
}

// Initializes vsock connection.
base::ScopedFD InitializeVSockConnection(uint32_t cid) {
  CHECK_GE(cid, adbd::kFirstGuestVmAddr);

  base::ScopedFD vsock_sock(socket(AF_VSOCK, SOCK_STREAM, 0));
  if (!vsock_sock.is_valid()) {
    PLOG(ERROR) << "Failed to create vsock socket";
    return base::ScopedFD();
  }
  struct sockaddr_vm addr_vm = {};
  addr_vm.svm_family = AF_VSOCK;
  addr_vm.svm_port = kAdbVsockPort;
  addr_vm.svm_cid = cid;
  if (HANDLE_EINTR(connect(vsock_sock.get(),
                           reinterpret_cast<const struct sockaddr*>(&addr_vm),
                           sizeof(addr_vm))) < 0) {
    PLOG(WARNING) << "Failed to connect to vsock socket";
    return base::ScopedFD();
  }
  LOG(INFO) << "Connected to ARCVM";
  return vsock_sock;
}

void StartArcVmAdbBridge(uint32_t cid) {
  constexpr base::TimeDelta kConnectInterval = base::Seconds(15);
  constexpr int kMaxRetries = 4;

  int retries = kMaxRetries;
  auto vsock_sock = InitializeVSockConnection(cid);
  while (!vsock_sock.is_valid()) {
    if (--retries < 0) {
      LOG(ERROR) << "Too many retries; giving up";
      _exit(EXIT_FAILURE);
    }
    // This path may be taken when guest's adbd hasn't started listening to the
    // socket yet. To work around the case, retry connecting to the socket after
    // a short sleep.
    // TODO(crbug.com/1126289): Remove the retry hack.
    base::PlatformThread::Sleep(kConnectInterval);
    vsock_sock = InitializeVSockConnection(cid);
  }

  // Channel direction is from device side, instead of USB perspective.
  const base::FilePath ep_out =
      base::FilePath(adbd::kFunctionFSPath).Append("ep1");
  base::ScopedFD ep_out_fd(
      HANDLE_EINTR(open(ep_out.value().c_str(), O_RDONLY)));
  if (!ep_out_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open OUT usb endpoint";
    _exit(EXIT_FAILURE);
  }
  auto sock_fd = vsock_sock.get();
  std::unique_ptr<ArcVmUsbToSock> ch_in =
      std::make_unique<ArcVmUsbToSock>(sock_fd, ep_out_fd.get());
  if (!ch_in->Start()) {
    LOG(ERROR) << "IN Channel failed to start";
    _exit(EXIT_FAILURE);
  }
  const base::FilePath ep_in =
      base::FilePath(adbd::kFunctionFSPath).Append("ep2");
  base::ScopedFD ep_in_fd(HANDLE_EINTR(open(ep_in.value().c_str(), O_WRONLY)));
  if (!ep_in_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open OUT usb endpoint";
    _exit(EXIT_FAILURE);
  }
  std::unique_ptr<ArcVmSockToUsb> ch_out =
      std::make_unique<ArcVmSockToUsb>(sock_fd, ep_in_fd.get());
  if (!ch_out->Start()) {
    LOG(ERROR) << "OUT Channel failed to start";
    _exit(EXIT_FAILURE);
  }
  LOG(INFO) << "arcvm adbd USB bridge started";
  // The function will not return here because the execution is waiting
  // for threads to join but that won't happen in normal cases.
}

}  // namespace adbd
