From 2b2775d52044e81a7560ae742220631879b7bb82 Mon Sep 17 00:00:00 2001 From: "rockot@chromium.org" Date: Mon, 28 Apr 2014 08:05:10 +0000 Subject: [PATCH] Block some HID devices from chrome.hid. This blacklists some specific types of HID devices from being accessible to the chrome.hid API. Namely, any keyboard, mice, other pointer devices, or system control inputs (such as power and reset buttons) are blocked and cannot be enumerated or opened by the consumers of the API. BUG=355022 R=rpaquay Review URL: https://codereview.chromium.org/258733002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266482 0039d316-1c4b-4281-b951-d872f2087c98 --- .../extensions/api/hid/hid_device_manager.cc | 48 +++++++++++- .../extensions/api/hid/hid_device_manager.h | 9 +++ device/hid/hid_usage_and_page.h | 73 +++++++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) diff --git a/chrome/browser/extensions/api/hid/hid_device_manager.cc b/chrome/browser/extensions/api/hid/hid_device_manager.cc index a8381b1c3255..45d82a6f87b4 100644 --- a/chrome/browser/extensions/api/hid/hid_device_manager.cc +++ b/chrome/browser/extensions/api/hid/hid_device_manager.cc @@ -11,6 +11,7 @@ #include "device/hid/hid_service.h" using device::HidService; +using device::HidUsageAndPage; namespace extensions { @@ -44,7 +45,8 @@ scoped_ptr HidDeviceManager::GetApiDevices( device::HidDeviceInfo device_info; if (hid_service->GetDeviceInfo(device_id, &device_info)) { if (device_info.vendor_id == vendor_id && - device_info.product_id == product_id) { + device_info.product_id == product_id && + IsDeviceAccessible(device_info)) { api::hid::HidDeviceInfo api_device_info; api_device_info.device_id = resource_id; api_device_info.vendor_id = device_info.vendor_id; @@ -114,4 +116,48 @@ void HidDeviceManager::UpdateDevices() { resource_ids_.swap(new_resource_ids); } +// static +// TODO(rockot): Add some tests for this. +bool HidDeviceManager::IsDeviceAccessible( + const device::HidDeviceInfo& device_info) { + for (std::vector::const_iterator iter = + device_info.usages.begin(); + iter != device_info.usages.end(); ++iter) { + if (!IsUsageAccessible(*iter)) { + return false; + } + } + return true; +} + +// static +bool HidDeviceManager::IsUsageAccessible( + const HidUsageAndPage& usage_and_page) { + if (usage_and_page.usage_page == HidUsageAndPage::kPageKeyboard) + return false; + + if (usage_and_page.usage_page != HidUsageAndPage::kPageGenericDesktop) + return true; + + uint16_t usage = usage_and_page.usage; + if (usage == HidUsageAndPage::kGenericDesktopPointer || + usage == HidUsageAndPage::kGenericDesktopMouse || + usage == HidUsageAndPage::kGenericDesktopKeyboard || + usage == HidUsageAndPage::kGenericDesktopKeypad) { + return false; + } + + if (usage >= HidUsageAndPage::kGenericDesktopSystemControl && + usage <= HidUsageAndPage::kGenericDesktopSystemWarmRestart) { + return false; + } + + if (usage >= HidUsageAndPage::kGenericDesktopSystemDock && + usage <= HidUsageAndPage::kGenericDesktopSystemDisplaySwap) { + return false; + } + + return true; +} + } // namespace extensions diff --git a/chrome/browser/extensions/api/hid/hid_device_manager.h b/chrome/browser/extensions/api/hid/hid_device_manager.h index 84a6e3022e53..c0abedd0ccf6 100644 --- a/chrome/browser/extensions/api/hid/hid_device_manager.h +++ b/chrome/browser/extensions/api/hid/hid_device_manager.h @@ -44,6 +44,15 @@ class HidDeviceManager : public BrowserContextKeyedAPI { void UpdateDevices(); + // Determines if a given device interface should be accessible to API + // consumers. In order for a device interface to be accessible, ALL of its + // specified usages must be accessible. + static bool IsDeviceAccessible(const device::HidDeviceInfo& device_info); + + // Determines if a given usage is available to API consumers. This is used to + // blacklist usages which could be security or privacy concerns. + static bool IsUsageAccessible(const device::HidUsageAndPage& usage_and_page); + base::ThreadChecker thread_checker_; int next_resource_id_; diff --git a/device/hid/hid_usage_and_page.h b/device/hid/hid_usage_and_page.h index e024b2b6b245..98ac80d6b544 100644 --- a/device/hid/hid_usage_and_page.h +++ b/device/hid/hid_usage_and_page.h @@ -46,6 +46,79 @@ struct HidUsageAndPage { kPageMediaCenter = 0xFFBC }; + // These usage enumerations are derived from the HID Usage Tables v1.11 spec. + enum GenericDesktopUsage { + kGenericDesktopUndefined = 0, + kGenericDesktopPointer = 1, + kGenericDesktopMouse = 2, + kGenericDesktopJoystick = 4, + kGenericDesktopGamePad = 5, + kGenericDesktopKeyboard = 6, + kGenericDesktopKeypad = 7, + kGenericDesktopMultiAxisController = 8, + kGenericDesktopX = 0x30, + kGenericDesktopY = 0x31, + kGenericDesktopZ = 0x32, + kGenericDesktopRx = 0x33, + kGenericDesktopRy = 0x34, + kGenericDesktopRz = 0x35, + kGenericDesktopSlider = 0x36, + kGenericDesktopDial = 0x37, + kGenericDesktopWheel = 0x38, + kGenericDesktopHatSwitch = 0x39, + kGenericDesktopCountedBuffer = 0x3a, + kGenericDesktopByteCount = 0x3b, + kGenericDesktopMotionWakeup = 0x3c, + kGenericDesktopStart = 0x3d, + kGenericDesktopSelect = 0x3e, + kGenericDesktopVx = 0x40, + kGenericDesktopVy = 0x41, + kGenericDesktopVz = 0x42, + kGenericDesktopVbrx = 0x43, + kGenericDesktopVbry = 0x44, + kGenericDesktopVbrz = 0x45, + kGenericDesktopVno = 0x46, + + kGenericDesktopSystemControl = 0x80, + kGenericDesktopSystemPowerDown = 0x81, + kGenericDesktopSystemSleep = 0x82, + kGenericDesktopSystemWakeUp = 0x83, + kGenericDesktopSystemContextMenu = 0x84, + kGenericDesktopSystemMainMenu = 0x85, + kGenericDesktopSystemAppMenu = 0x86, + kGenericDesktopSystemMenuHelp = 0x87, + kGenericDesktopSystemMenuExit = 0x88, + kGenericDesktopSystemMenuSelect = 0x89, + kGenericDesktopSystemMenuRight = 0x8a, + kGenericDesktopSystemMenuLeft = 0x8b, + kGenericDesktopSystemMenuUp = 0x8c, + kGenericDesktopSystemMenuDown = 0x8d, + kGenericDesktopSystemColdRestart = 0x8e, + kGenericDesktopSystemWarmRestart = 0x8f, + + kGenericDesktopDPadUp = 0x90, + kGenericDesktopDPadDown = 0x91, + kGenericDesktopDPadLeft = 0x92, + kGenericDesktopDPadRight = 0x93, + + kGenericDesktopSystemDock = 0xa0, + kGenericDesktopSystemUndock = 0xa1, + kGenericDesktopSystemSetup = 0xa2, + kGenericDesktopSystemBreak = 0xa3, + kGenericDesktopSystemDebuggerBreak = 0xa4, + kGenericDesktopApplicationBreak = 0xa5, + kGenericDesktopApplicationDebuggerBreak = 0xa6, + kGenericDesktopSystemSpeakerMute = 0xa7, + kGenericDesktopSystemHibernate = 0xa8, + kGenericDesktopSystemDisplayInvert = 0xb0, + kGenericDesktopSystemDisplayInternal = 0xb1, + kGenericDesktopSystemDisplayExternal = 0xb2, + kGenericDesktopSystemDisplayBoth = 0xb3, + kGenericDesktopSystemDisplayDual = 0xb4, + kGenericDesktopSystemDisplayToggle = 0xb5, + kGenericDesktopSystemDisplaySwap = 0xb6, + }; + HidUsageAndPage(uint16_t usage, Page usage_page) : usage(usage), usage_page(usage_page) {} ~HidUsageAndPage() {}