// Copyright (c) 2012 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 "permission_broker/deny_claimed_usb_device_rule.h"

#include <libudev.h>
#include <linux/usb/ch9.h>

#include <iterator>
#include <memory>
#include <string>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "permission_broker/udev_scopers.h"

#include <base/check.h>

using policy::DevicePolicy;

namespace {

const uint32_t kAdbClass = 0xff;
const uint32_t kAdbSubclass = 0x42;
const uint32_t kAdbProtocol = 0x1;

enum class RemovableAttr {
  kUnknown,
  kFixed,
  kRemovable,
};

RemovableAttr ParseRemovableSysattr(const std::string& removable) {
  if (removable == "fixed") {
    return RemovableAttr::kFixed;
  } else if (removable == "removable") {
    return RemovableAttr::kRemovable;
  } else {
    if (removable != "unknown") {
      LOG(WARNING) << "Unexpected value for removable sysattr: '" << removable
                   << "'";
    }
    return RemovableAttr::kUnknown;
  }
}

RemovableAttr GetRemovableSysattr(udev_device* device) {
  const char* removable = udev_device_get_sysattr_value(device, "removable");
  if (!removable) {
    return RemovableAttr::kUnknown;
  }
  return ParseRemovableSysattr(removable);
}

bool GetUIntSysattr(udev_device* device, const char* key, uint32_t* val) {
  CHECK(val);

  const char* str_val = udev_device_get_sysattr_value(device, key);
  return str_val && base::HexStringToUInt(str_val, val);
}

// Check if a USB vendor:product ID pair is in the provided list.
// Entries in the list with |product_id| of 0 match any product with the
// corresponding |vendor_id|.
template <typename Iterator>
bool UsbDeviceListContainsId(Iterator first,
                             Iterator last,
                             uint16_t vendor_id,
                             uint16_t product_id) {
  while (first != last) {
    if (first->vendor_id == vendor_id &&
        (!first->product_id || first->product_id == product_id))
      return true;
    ++first;
  }
  return false;
}

}  // namespace

namespace permission_broker {

DenyClaimedUsbDeviceRule::DenyClaimedUsbDeviceRule()
    : UsbSubsystemUdevRule("DenyClaimedUsbDeviceRule"), policy_loaded_(false) {}

DenyClaimedUsbDeviceRule::~DenyClaimedUsbDeviceRule() = default;

bool DenyClaimedUsbDeviceRule::LoadPolicy() {
  usb_allow_list_.clear();

  auto policy_provider = std::make_unique<policy::PolicyProvider>();
  policy_provider->Reload();

  // No available policies.
  if (!policy_provider->device_policy_is_loaded())
    return false;

  const policy::DevicePolicy* policy = &policy_provider->GetDevicePolicy();
  return policy->GetUsbDetachableWhitelist(&usb_allow_list_);
}

bool DenyClaimedUsbDeviceRule::IsDeviceDetachableByPolicy(udev_device* device) {
  // Retrieve the device policy for detachable USB devices if needed.
  if (!policy_loaded_)
    policy_loaded_ = LoadPolicy();
  if (!policy_loaded_)
    return false;

  // Check whether this USB device is allowed.
  uint32_t vendor_id, product_id;
  if (!GetUIntSysattr(device, "idVendor", &vendor_id) ||
      !GetUIntSysattr(device, "idProduct", &product_id))
    return false;

  return UsbDeviceListContainsId(usb_allow_list_.begin(), usb_allow_list_.end(),
                                 vendor_id, product_id);
}

bool DenyClaimedUsbDeviceRule::IsInterfaceAdb(udev_device* device) {
  uint32_t intf_class, intf_subclass, intf_protocol;
  if (!GetUIntSysattr(device, "bInterfaceClass", &intf_class) ||
      !GetUIntSysattr(device, "bInterfaceSubClass", &intf_subclass) ||
      !GetUIntSysattr(device, "bInterfaceProtocol", &intf_protocol))
    return false;

  return intf_class == kAdbClass && intf_subclass == kAdbSubclass &&
         intf_protocol == kAdbProtocol;
}

bool IsInterfaceUsbSerial(udev_device* iface) {
  // Search all children of the interface in the 'usb-serial' subsystem
  // this includes all the USB-serial converter and most micro-controllers
  // USB bulk endpoints presenting a serial-like interface but not CDC-ACM
  // devices (e.g. modems or boards pretending to be one)
  udev* udev = udev_device_get_udev(iface);
  ScopedUdevEnumeratePtr enum_serial(udev_enumerate_new(udev));
  udev_enumerate_add_match_subsystem(enum_serial.get(), "usb-serial");
  udev_enumerate_add_match_parent(enum_serial.get(), iface);
  udev_enumerate_scan_devices(enum_serial.get());

  struct udev_list_entry* entry = nullptr;
  udev_list_entry_foreach(entry,
                          udev_enumerate_get_list_entry(enum_serial.get())) {
    // a usb-serial driver is connected to this interface
    LOG(INFO) << "Found usb-serial interface.";
    return true;
  }
  return false;
}

bool IsInterfaceStorage(udev_device* iface) {
  uint32_t interface_class;
  if (!GetUIntSysattr(iface, "bInterfaceClass", &interface_class))
    return false;
  // This matches USB drives, SD adapters, and so on.
  return interface_class == USB_CLASS_MASS_STORAGE;
}

bool IsInterfaceSafeToDetach(udev_device* iface) {
  // Normally the permission_broker prevents users from interfering with the
  // system usage of a USB device.

  // But in particular cases, a USB interface is deemed 'safe to detach' from
  // its kernel driver if the purpose of the driver is only exposing it to apps.
  // e.g. below the usb serial interfaces are only used by the chrome.serial
  // and WebSerial external API rather than in any intrinsic system use.

  // Storage devices are a special case that we allow to be shared to Guest VMs.
  // Chrome provides extra protections to avoid exposing these devices to
  // non-Guest VM components.

  return IsInterfaceUsbSerial(iface) || IsInterfaceStorage(iface);
}

bool IsDeviceAllowedSerial(udev_device* device) {
  // The Arduino vendor IDs are derived from https://raw.githubusercontent.com
  // /arduino/ArduinoCore-avr/master/boards.txt
  // /arduino/ArduinoCore-sam/master/boards.txt
  // /arduino/ArduinoCore-samd/master/boards.txt
  // using
  // grep -o -E  "vid\..*=(0x.*)" *boards.txt | sed "s/vid\..=//g" | sort -f | \
  // uniq -i
  const DevicePolicy::UsbDeviceId kAllowedIds[] = {
      {0x0d28, 0x0204},  // BBC micro:bit

      {0x2341, 0},  // Arduino
      {0x1b4f, 0},  // Sparkfun
      {0x239a, 0},  // Adafruit
      {0x2a03, 0},  // doghunter.org
      {0x10c4, 0},  // Silicon Labs

      {0x2c99, 0},  // Prusa Research

      {0x2e8a, 0},  // Raspberry Pi

      {0x18d1, 0x5002},  // Google Servo V2
      {0x18d1, 0x5003},  // Google Servo V2
      {0x18d1, 0x500a},  // Google twinkie
      {0x18d1, 0x500b},  // Google Plankton
      {0x18d1, 0x500c},  // Google Plankton
      {0x18d1, 0x5014},  // Google Cr50
      {0x18d1, 0x501a},  // Google Servo micro
      {0x18d1, 0x501b},  // Google Servo V4
      {0x18d1, 0x501f},  // Google Suzyq
      {0x18d1, 0x5020},  // Google Sweetberry
      {0x18d1, 0x5027},  // Google Tigertail
      {0x18d1, 0x5036},  // Google Chocodile

      {0x1d50, 0x6140},  // QuickLogic QuickFeather evaluation board bootloader
      {0x1d50, 0x6130},  // TinyFPGA BX Bootloader old openmoko VID:PID
      {0x1209, 0x2100},  // TinyFPGA BX Bootloader new pid.codes VID:PID
      {0x1209, 0x5bf0},  // Arty FPGA board
  };
  uint32_t vendor_id, product_id;
  if (!GetUIntSysattr(device, "idVendor", &vendor_id) ||
      !GetUIntSysattr(device, "idProduct", &product_id))
    return false;

  return UsbDeviceListContainsId(std::begin(kAllowedIds), std::end(kAllowedIds),
                                 vendor_id, product_id);
}

Rule::Result DenyClaimedUsbDeviceRule::ProcessUsbDevice(udev_device* device) {
  const char* device_syspath = udev_device_get_syspath(device);
  if (!device_syspath) {
    return DENY;
  }

  udev* udev = udev_device_get_udev(device);
  ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev));
  udev_enumerate_add_match_subsystem(enumerate.get(), "usb");
  udev_enumerate_scan_devices(enumerate.get());

  bool found_claimed_interface = false;
  bool found_unclaimed_interface = false;
  bool found_adb_interface = false;
  bool found_only_safe_interfaces = true;
  struct udev_list_entry* entry = nullptr;
  udev_list_entry_foreach(entry,
                          udev_enumerate_get_list_entry(enumerate.get())) {
    const char* entry_path = udev_list_entry_get_name(entry);
    ScopedUdevDevicePtr child(udev_device_new_from_syspath(udev, entry_path));

    // Find out if this entry's direct parent is the device in question.
    struct udev_device* parent = udev_device_get_parent(child.get());
    if (!parent) {
      continue;
    }
    const char* parent_syspath = udev_device_get_syspath(parent);
    if (!parent_syspath || strcmp(device_syspath, parent_syspath) != 0) {
      continue;
    }

    const char* child_type = udev_device_get_devtype(child.get());
    if (!child_type || strcmp(child_type, "usb_interface") != 0) {
      // If this is not a usb_interface node then something is wrong, fail safe.
      LOG(WARNING) << "Found a child '" << entry_path
                   << "' with unexpected type: "
                   << (child_type ? child_type : "(null)");
      return DENY;
    }

    const char* driver = udev_device_get_driver(child.get());
    if (driver) {
      LOG(INFO) << "Found claimed interface with driver: " << driver;
      found_claimed_interface = true;
      found_only_safe_interfaces =
          found_only_safe_interfaces && IsInterfaceSafeToDetach(child.get());
    } else {
      found_unclaimed_interface = true;
    }

    if (IsInterfaceAdb(child.get())) {
      LOG(INFO) << "Found ADB interface.";
      found_adb_interface = true;
    }
  }

  if (found_claimed_interface) {
    // Don't allow detaching the driver from fixed (internal) USB devices.
    if (GetRemovableSysattr(device) == RemovableAttr::kFixed) {
      LOG(INFO) << "Denying fixed USB device with driver.";
      return DENY;
    }

    if (found_only_safe_interfaces)
      LOG(INFO) << "Found only detachable interface(s), safe to claim.";

    if (IsDeviceDetachableByPolicy(device) || IsDeviceAllowedSerial(device) ||
        found_adb_interface || found_only_safe_interfaces)
      return ALLOW_WITH_DETACH;
    else
      return found_unclaimed_interface ? ALLOW_WITH_LOCKDOWN : DENY;
  } else {
    return IGNORE;
  }
}

}  // namespace permission_broker
