// 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_hidraw_device_rule.h"

#include <bits/wordsize.h>
#include <libudev.h>
#include <linux/input.h>

#include <algorithm>
#include <limits>
#include <string>
#include <vector>

#include "base/containers/adapters.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "permission_broker/udev_scopers.h"

namespace permission_broker {

namespace {

const std::vector<std::string> kGenericSubsystems = {
    "bluetooth", "hid", "hidraw", "rfkill", "usb", "usbmisc"};

const char kLogitechUnifyingReceiverDriver[] = "logitech-djreceiver";
const char kThingmDriver[] = "thingm";

const base::StringPiece kJoydevPrefix = "/dev/input/js";

const size_t kAllowedAbsCapabilities[] = {
    ABS_X, ABS_Y, ABS_Z,
    ABS_RX, ABS_RY, ABS_RZ,
    ABS_THROTTLE, ABS_RUDDER, ABS_WHEEL, ABS_GAS, ABS_BRAKE,
    ABS_HAT0X, ABS_HAT0Y,
    ABS_HAT1X, ABS_HAT1Y,
    ABS_HAT2X, ABS_HAT2Y,
    ABS_HAT3X, ABS_HAT3Y,
    ABS_MISC,
};

bool ParseInputCapabilities(const char* input, std::vector<uint64_t>* output) {
  // The kernel expresses capabilities as a bitfield, broken into long-sized
  // chunks encoded in hexadecimal.
  std::vector<std::string> chunks =
      base::SplitString(input, " ", base::KEEP_WHITESPACE,
                        base::SPLIT_WANT_ALL);

  output->clear();
  output->reserve(chunks.size());

  // The most-significant chunk of the bitmask is stored first, iterate over
  // the chunks in reverse so that the result is easier to work with.
  for (const std::string& chunk : base::Reversed(chunks)) {
    uint64_t value = 0;
    if (!base::HexStringToUInt64(chunk, &value)) {
      LOG(ERROR) << "Failed to parse: " << chunk;
      return false;
    }
    // NOLINTNEXTLINE(runtime/int)
    if (value > std::numeric_limits<unsigned long>::max()) {
      LOG(ERROR) << "Chunk value too large for platform: " << value;
      return false;
    }
    output->push_back(value);
  }

  if (__WORDSIZE == 32) {
    // Compact the vector of 32-bit values into a vector of 64-bit values.
    for (size_t i = 0; i < chunks.size(); i += 2) {
      (*output)[i / 2] = (*output)[i];
      if (i + 1 < chunks.size())
        (*output)[i / 2] |= (uint64_t)((*output)[i + 1]) << 32;
    }
    output->resize((chunks.size() + 1) / 2);
  }

  return true;
}

bool IsCapabilityBitSet(const std::vector<uint64_t>& bitfield, size_t bit) {
  size_t offset = bit / (sizeof(uint64_t) * 8);
  if (offset >= bitfield.size())
    return false;

  return bitfield[offset] & (1ULL << (bit - offset * sizeof(bitfield[0]) * 8));
}

bool AnyCapabilityBitsSet(const std::vector<uint64_t>& bitfield) {
  for (auto value : bitfield) {
    if (value != 0)
      return true;
  }
  return false;
}

void UnsetCapabilityBit(std::vector<uint64_t>* bitfield, size_t bit) {
  size_t offset = bit / (sizeof(uint64_t) * 8);
  if (offset >= bitfield->size())
    return;

  (*bitfield)[offset] &= ~(1ULL << (bit - offset * sizeof(uint64_t) * 8));
}

constexpr bool IsCfmDevice() {
  return USE_CFM_ENABLED_DEVICE;
}

// Joydev devices expose a devnode string with the format:
//     /dev/input/js#
// Where # is the numeric index of the joydev device.
bool IsJoydevDeviceNode(base::StringPiece devnode) {
  // Match the devnode prefix.
  if (!base::StartsWith(devnode, kJoydevPrefix, base::CompareCase::SENSITIVE))
    return false;

  // Match if the suffix parses as a non-negative integer.
  devnode.remove_prefix(kJoydevPrefix.length());
  int joydev_index = 0;
  if (!base::StringToInt(devnode, &joydev_index))
    return false;
  return joydev_index >= 0;
}

}  // namespace

DenyClaimedHidrawDeviceRule::DenyClaimedHidrawDeviceRule()
    : HidrawSubsystemUdevRule("DenyClaimedHidrawDeviceRule") {}

Rule::Result DenyClaimedHidrawDeviceRule::ProcessHidrawDevice(
    struct udev_device* device) {
  struct udev_device* hid_parent =
      udev_device_get_parent_with_subsystem_devtype(device, "hid", nullptr);
  if (!hid_parent) {
    // A hidraw device without a HID parent, we don't know what this can be.
    return DENY;
  }

  const char* hid_parent_driver = udev_device_get_driver(hid_parent);
  if (hid_parent_driver) {
    // Add an exception to the rule for Logitech Unifying receiver. This hidraw
    // device is a parent of devices that have input subsystem. Yet the traffic
    // to those children is not available on the hidraw node of the receiver,
    // so it is safe to whitelist it.
    if (strcmp(hid_parent_driver, kLogitechUnifyingReceiverDriver) == 0) {
      LOG(INFO) << "Found Logitech Unifying receiver. Skipping rule.";
      return IGNORE;
    }

    // An led subsystem driver is provided for this device but for historical
    // reasons we want to continue to allow raw HID access as well.
    if (strcmp(hid_parent_driver, kThingmDriver) == 0) {
      LOG(INFO) << "Found ThingM blink(1). Skipping rule.";
      return IGNORE;
    }
  }

  std::string hid_parent_path(udev_device_get_syspath(hid_parent));
  std::string usb_interface_path;
  struct udev_device* usb_interface =
      udev_device_get_parent_with_subsystem_devtype(
          device, "usb", "usb_interface");

  if (usb_interface)
    usb_interface_path = udev_device_get_syspath(usb_interface);

  // Count the number of children of the same HID parent as us.
  int hid_siblings = 0;

  bool should_sibling_subsystem_exclude_access = false;

  // Scan all children of the USB interface for subsystems other than generic
  // USB or HID, and all the children of the same HID parent device.
  // The presence of such subsystems is an indication that the device is in
  // use by another driver.
  //
  // Because udev lacks the ability to filter an enumeration by arbitrary
  // ancestor properties (e.g. "enumerate all nodes with a usb_interface
  // ancestor") we have to scan the entire set of devices to find potential
  // matches.
  struct udev* udev = udev_device_get_udev(device);
  ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev));
  udev_enumerate_scan_devices(enumerate.get());
  struct udev_list_entry* entry;
  udev_list_entry_foreach(entry,
                          udev_enumerate_get_list_entry(enumerate.get())) {
    const char* syspath = udev_list_entry_get_name(entry);
    ScopedUdevDevicePtr child(udev_device_new_from_syspath(udev, syspath));
    struct udev_device* child_usb_interface =
        udev_device_get_parent_with_subsystem_devtype(
            child.get(), "usb", "usb_interface");
    struct udev_device* child_hid_parent =
        udev_device_get_parent_with_subsystem_devtype(
            child.get(), "hid", nullptr);
    if (!child_usb_interface && !child_hid_parent) {
      continue;
    }
    // Some gamepads expose functionality that is only accessible through the
    // hidraw node. To allow hidraw access to such devices, skip the sibling
    // subsystem and capabilities checks if one of the siblings is a joydev
    // device.
    const char* devnode = udev_device_get_devnode(child.get());
    if (devnode && IsJoydevDeviceNode(devnode))
      return IGNORE;

    // This device shares a USB interface with the hidraw device in question.
    // Check its subsystem to see if it should block hidraw access.
    if (!should_sibling_subsystem_exclude_access &&
        usb_interface && child_usb_interface &&
        usb_interface_path == udev_device_get_syspath(child_usb_interface)) {
      should_sibling_subsystem_exclude_access =
          ShouldSiblingSubsystemExcludeHidAccess(child.get());
    }
    // This device shares the same HID device as parent, count it.
    if (child_hid_parent &&
        hid_parent_path == udev_device_get_syspath(child_hid_parent)) {
      hid_siblings++;
    }
  }

  // If the underlying device presents other interfaces, deny access to the
  // hidraw node as it may allow access to private data transmitted over these
  // interfaces.
  if (should_sibling_subsystem_exclude_access)
    return DENY;

  // If the underlying HID device presents no other interface than hidraw,
  // we can use it.
  // USB devices have already been filtered directly in the loop above.
  if (!usb_interface && hid_siblings != 1)
    return DENY;

  return IGNORE;
}

bool DenyClaimedHidrawDeviceRule::ShouldSiblingSubsystemExcludeHidAccess(
    struct udev_device* sibling) {
  const char* subsystem = udev_device_get_subsystem(sibling);
  if (!subsystem) {
    return false;
  }

  // Generic subsystems (such as "hid" or "usb") should never exclude access.
  if (std::find(kGenericSubsystems.begin(), kGenericSubsystems.end(),
                subsystem) != kGenericSubsystems.end()) {
    return false;
  }

  // Don't block hidraw access due to leds subsystem.
  if (IsCfmDevice() && strcmp(subsystem, "leds") == 0) {
    return false;
  }

  if (strcmp(subsystem, "input") == 0 &&
      !ShouldInputCapabilitiesExcludeHidAccess(
          udev_device_get_sysattr_value(sibling, "capabilities/abs"),
          udev_device_get_sysattr_value(sibling, "capabilities/rel"),
          udev_device_get_sysattr_value(sibling, "capabilities/key"))) {
    return false;
  }

  return true;
}

bool DenyClaimedHidrawDeviceRule::ShouldInputCapabilitiesExcludeHidAccess(
    const char* abs_capabilities,
    const char* rel_capabilities,
    const char* key_capabilities) {
  bool has_absolute_mouse_axes = false;
  bool has_absolute_mouse_keys = false;
  std::vector<uint64_t> capabilities;
  if (abs_capabilities) {
    if (!ParseInputCapabilities(abs_capabilities, &capabilities)) {
      // Parse error? Fail safe.
      return true;
    }

    // If the device has ABS_X and ABS_Y and no other absolute axes, it may be
    // an absolute pointing device.
    if (IsCapabilityBitSet(capabilities, ABS_X) &&
        IsCapabilityBitSet(capabilities, ABS_Y)) {
      UnsetCapabilityBit(&capabilities, ABS_X);
      UnsetCapabilityBit(&capabilities, ABS_Y);
      if (!AnyCapabilityBitsSet(capabilities))
        has_absolute_mouse_axes = true;
    }

    // Remove whitelisted capabilities. Any other absolute pointer capabilities
    // exclude access.
    for (size_t i = 0; i < base::size(kAllowedAbsCapabilities); ++i)
      UnsetCapabilityBit(&capabilities, kAllowedAbsCapabilities[i]);
    if (AnyCapabilityBitsSet(capabilities))
      return true;
  }

  if (rel_capabilities) {
    if (!ParseInputCapabilities(rel_capabilities, &capabilities)) {
      // Parse error? Fail safe.
      return true;
    }
    // Any relative pointer capabilities exclude access.
    if (AnyCapabilityBitsSet(capabilities))
      return true;
  }

  if (key_capabilities) {
    if (!ParseInputCapabilities(key_capabilities, &capabilities)) {
      // Parse error? Fail safe.
      return true;
    }

    // If the device has BTN_LEFT, BTN_RIGHT, BTN_MIDDLE and no other keys,
    // it may be an absolute pointing device.
    if (IsCapabilityBitSet(capabilities, BTN_LEFT) &&
        IsCapabilityBitSet(capabilities, BTN_RIGHT) &&
        IsCapabilityBitSet(capabilities, BTN_MIDDLE)) {
      UnsetCapabilityBit(&capabilities, BTN_LEFT);
      UnsetCapabilityBit(&capabilities, BTN_RIGHT);
      UnsetCapabilityBit(&capabilities, BTN_MIDDLE);
      if (!AnyCapabilityBitsSet(capabilities))
        has_absolute_mouse_keys = true;
    }

    // Any key code <= KEY_KPDOT (83) excludes access.
    for (int key = 0; key <= KEY_KPDOT; key++) {
      if (IsCapabilityBitSet(capabilities, key)) {
        return true;
      }
    }
    // Braille dots are outside the "normal keyboard keys" range.
    for (int key = KEY_BRL_DOT1; key <= KEY_BRL_DOT10; key++) {
      if (IsCapabilityBitSet(capabilities, key)) {
        return true;
      }
    }
  }

  // Exclude absolute pointing devices that match joydev's capabilities check.
  if (has_absolute_mouse_axes && has_absolute_mouse_keys)
    return true;

  return false;
}

}  // namespace permission_broker
