Skip to content

Commit

Permalink
Block some HID devices from chrome.hid.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rockot@chromium.org committed Apr 28, 2014
1 parent 9205af9 commit 2b2775d
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 1 deletion.
48 changes: 47 additions & 1 deletion chrome/browser/extensions/api/hid/hid_device_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "device/hid/hid_service.h"

using device::HidService;
using device::HidUsageAndPage;

namespace extensions {

Expand Down Expand Up @@ -44,7 +45,8 @@ scoped_ptr<base::ListValue> 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;
Expand Down Expand Up @@ -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<device::HidUsageAndPage>::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
9 changes: 9 additions & 0 deletions chrome/browser/extensions/api/hid/hid_device_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down
73 changes: 73 additions & 0 deletions device/hid/hid_usage_and_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Expand Down

0 comments on commit 2b2775d

Please sign in to comment.