// Copyright 2020 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 "pciguard/sysfs_utils.h"

#include <base/command_line.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <brillo/syslog_logging.h>

#include <set>
#include <string>
#include <sysexits.h>

namespace pciguard {

namespace {

// Actual driver allowlist.
const char* kAllowlist[] = {
    // TODO(b/163121310): Finalize allowlist
    "pcieport",  // PCI Core services - AER, Hotplug etc.
    "xhci_hcd",  // XHCI host controller driver.
    "nvme",      // PCI Express NVME host controller driver.
    "ahci",      // AHCI driver
    "igb",       // Intel Gigabit Ethernet driver
};

}  // namespace

SysfsUtils::SysfsUtils() : SysfsUtils(FilePath("/")) {}

SysfsUtils::SysfsUtils(FilePath root)
    : allowlist_path_(root.Append("sys/bus/pci/drivers_allowlist")),
      pci_lockdown_path_(root.Append("sys/bus/pci/drivers_allowlist_lockdown")),
      pci_rescan_path_(root.Append("sys/bus/pci/rescan")),
      tbt_devices_path_(root.Append("sys/bus/thunderbolt/devices")),
      pci_devices_path_(root.Append("sys/bus/pci/devices")) {}

int SysfsUtils::SetAuthorizedAttribute(base::FilePath devpath, bool enable) {
  if (!PathExists(devpath)) {
    PLOG(ERROR) << "Path doesn't exist : " << devpath;
    return EXIT_FAILURE;
  }

  base::FilePath symlink;
  // Check it is a thunderbolt path
  if (!base::ReadSymbolicLink(devpath.Append("subsystem"), &symlink) ||
      !base::EndsWith(symlink.value(), "/bus/thunderbolt",
                      base::CompareCase::SENSITIVE)) {
    LOG(ERROR) << "Not a thunderbolt devpath: " << devpath;
    return EXIT_FAILURE;
  }

  base::FilePath authorized_path = devpath.Append("authorized");
  std::string authorized;

  // Proceed only if authorized file exists
  if (!base::ReadFileToString(authorized_path, &authorized))
    return EXIT_SUCCESS;

  // Nevermind if no need to change the state.
  if (!authorized.empty() &&
      ((enable && authorized[0] != '0') || (!enable && authorized[0] == '0')))
    return EXIT_SUCCESS;

  auto val = "0";
  if (enable) {
    LOG(INFO) << "Authorizing:" << devpath;
    val = "1";
  } else {
    LOG(INFO) << "Deauthorizing:" << devpath;
  }

  if (base::WriteFile(authorized_path, val, 1) != 1) {
    PLOG(ERROR) << "Couldn't write " << val << " to " << authorized_path;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

int SysfsUtils::DeauthorizeThunderboltDev(base::FilePath devpath) {
  return SetAuthorizedAttribute(devpath, false);
}

int SysfsUtils::OnInit(void) {
  if (!base::PathIsWritable(allowlist_path_) ||
      !base::PathIsWritable(pci_lockdown_path_)) {
    PLOG(ERROR) << "Kernel is missing needed support for external PCI security";
    return EX_OSFILE;
  }

  if (base::WriteFile(pci_lockdown_path_, "1", 1) != 1) {
    PLOG(ERROR) << "Couldn't write 1 to " << pci_lockdown_path_;
    return EX_IOERR;
  }

  for (auto drvr_name : kAllowlist) {
    if (base::WriteFile(allowlist_path_, drvr_name, sizeof(drvr_name)) ==
        sizeof(drvr_name))
      LOG(INFO) << "Allowed " << drvr_name;
    else
      PLOG(ERROR) << "Couldn't allow " << drvr_name;
  }
  return EX_OK;
}

int SysfsUtils::AuthorizeThunderboltDev(base::FilePath devpath) {
  return SetAuthorizedAttribute(devpath, true);
}

int SysfsUtils::AuthorizeAllDevices(void) {
  LOG(INFO) << "Authorizing all external PCI devices";

  // Allow drivers to bind to PCI devices. This also binds any PCI devices
  // that may have been hotplugged "into" external peripherals, while the
  // screen was locked.
  if (base::WriteFile(pci_lockdown_path_, "0", 1) != 1) {
    PLOG(ERROR) << "Couldn't write 0 to " << pci_lockdown_path_;
    return EXIT_FAILURE;
  }

  int ret = EXIT_SUCCESS;

  // Add any PCI devices that we removed when the user had logged off.
  if (base::WriteFile(pci_rescan_path_, "1", 1) != 1) {
    PLOG(ERROR) << "Couldn't write 1 to " << pci_rescan_path_;
    ret = EXIT_FAILURE;
  }

  // Create an BFS ordered set of thunderbolt devices.
  auto cmp = [](const base::FilePath& dev1, const base::FilePath& dev2) {
    base::FilePath symlink1, symlink2;
    (void)base::ReadSymbolicLink(dev1, &symlink1);
    (void)base::ReadSymbolicLink(dev2, &symlink2);
    return symlink1 < symlink2;
  };
  std::set<base::FilePath, decltype(cmp)> thunderbolt_devs(cmp);
  base::FileEnumerator iter(tbt_devices_path_, false,
                            base::FileEnumerator::DIRECTORIES);
  for (auto devpath = iter.Next(); !devpath.empty(); devpath = iter.Next())
    thunderbolt_devs.insert(devpath);

  // Authorize the thunderbolt devices in BFS order (sorting using the
  // symlinks to which the devices point, gives us BFS). This is
  // required because if a parent is deauthorized, the children are
  // automatically deauthorized, but vice versa is not true.
  for (auto dev : thunderbolt_devs) {
    if (AuthorizeThunderboltDev(dev))
      ret = EXIT_FAILURE;
  }

  return ret;
}

int SysfsUtils::DenyNewDevices(void) {
  LOG(INFO) << "Will deny all new external PCI devices";

  // Deny drivers to bind to any *new* external PCI devices.
  if (base::WriteFile(pci_lockdown_path_, "1", 1) != 1) {
    PLOG(ERROR) << "Couldn't write 1 to " << pci_lockdown_path_;
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}

int SysfsUtils::DeauthorizeAllDevices(void) {
  int ret = EXIT_SUCCESS;
  if (DenyNewDevices())
    return EXIT_FAILURE;

  LOG(INFO) << "Deauthorizing all external PCI devices";

  // Remove all untrusted (external) PCI devices.
  base::FileEnumerator iter(pci_devices_path_, false,
                            base::FileEnumerator::DIRECTORIES);
  for (auto devpath = iter.Next(); !devpath.empty(); devpath = iter.Next()) {
    std::string untrusted;

    // It is possible this device may already been have removed (as an effect
    // of its parent being removed).
    if (!PathExists(devpath))
      continue;

    // Proceed only if there is an "untrusted" file.
    if (!base::ReadFileToString(devpath.Append("untrusted"), &untrusted) ||
        untrusted.empty()) {
      PLOG(ERROR) << "Couldn't read " << devpath << "/untrusted";
      ret = EXIT_FAILURE;
      continue;
    }

    // Nevermind the trusted devices.
    if (untrusted[0] == '0')
      continue;

    // Remove untrusted device.
    if (base::WriteFile(devpath.Append("remove"), "1", 1) != 1) {
      PLOG(ERROR) << "Couldn't remove untrusted device " << devpath;
      ret = EXIT_FAILURE;
    }
  }

  // Deauthorize all thunderbolt devices.
  base::FileEnumerator tbt_iter(tbt_devices_path_, false,
                                base::FileEnumerator::DIRECTORIES);
  for (auto devpath = tbt_iter.Next(); !devpath.empty();
       devpath = tbt_iter.Next()) {
    if (DeauthorizeThunderboltDev(devpath))
      ret = EXIT_FAILURE;
  }
  return ret;
}

}  // namespace pciguard
