| // 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_unsafe_hidraw_device_rule.h" |
| |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| #include "base/logging.h" |
| |
| #define MAKE_DESCRIPTOR(array) GenerateReportDescriptor(array, sizeof(array)) |
| |
| namespace permission_broker { |
| |
| namespace { |
| |
| // Some invalid descriptors. |
| const uint8_t kInvalidDescriptor0[] = { 0x1 }; |
| const uint8_t kInvalidDescriptor1[] = { 0x6 }; |
| const uint8_t kInvalidDescriptor2[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
| |
| // Interface descriptor contents from a LUFA TinyHID firmware. |
| const uint8_t kLUFATestFirmwareDescriptor[] = { |
| 0x6, 0x0, 0xff, 0x9, 0x1, 0xa1, 0x1, 0x9, 0x2, 0x15, 0x0, 0x25, 0xff, 0x75, |
| 0x8, 0x95, 0x8, 0x81, 0x2, 0x9, 0x3, 0x15, 0x0, 0x25, 0xff, 0x75, 0x8, 0x95, |
| 0x8, 0x91, 0x2, 0xc0 |
| }; |
| |
| // Interface descriptor contents from a Logitech G13 controller. |
| const uint8_t kLogitechG13Descriptor[] = { |
| 0x6, 0x0, 0xff, 0x9, 0x0, 0xa1, 0x1, 0x15, 0x0, 0x26, 0xff, 0x0, 0x9, 0x1, |
| 0x85, 0x1, 0x95, 0x7, 0x75, 0x8, 0x81, 0x2, 0x85, 0x3, 0x9, 0x2, 0x96, 0xdf, |
| 0x3, 0x91, 0x2, 0x85, 0x7, 0x9, 0x3, 0x95, 0x4, 0xb1, 0x2, 0x85, 0x4, 0x9, |
| 0x4, 0xb1, 0x2, 0x85, 0x5, 0x9, 0x5, 0xb1, 0x2, 0x85, 0x6, 0x9, 0x6, 0x96, |
| 0x1, 0x1, 0xb1, 0x2, 0xc0 |
| }; |
| |
| // Interface descriptor contents from the keyboard interface of GCS1784 |
| // KVM Switch. |
| const uint8_t kSampleKeyboardDescriptor[] = { |
| 0x5, 0x1, 0x9, 0x6, 0xa1, 0x1, 0x5, 0x7, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x0, |
| 0x25, 0x1, 0x75, 0x1, 0x95, 0x8, 0x81, 0x2, 0x95, 0x1, 0x75, 0x8, 0x81, 0x1, |
| 0x95, 0x5, 0x75, 0x1, 0x5, 0x8, 0x19, 0x1, 0x29, 0x5, 0x91, 0x2, 0x95, 0x1, |
| 0x75, 0x3, 0x91, 0x1, 0x5, 0x7, 0x95, 0x6, 0x75, 0x8, 0x15, 0x0, 0x26, 0xff, |
| 0x0, 0x19, 0x0, 0x2a, 0xff, 0x0, 0x81, 0x0, 0xc0 |
| }; |
| |
| // Interface descriptor contents from the mouse interface of an GCS1784 |
| // KVM Switch. |
| const uint8_t kSampleMouseDescriptor[] = { |
| 0x5, 0x1, 0x9, 0x2, 0xa1, 0x1, 0x9, 0x1, 0xa1, 0x0, 0x5, 0x9, 0x19, 0x1, 0x29, |
| 0x5, 0x15, 0x0, 0x25, 0x1, 0x95, 0x5, 0x75, 0x1, 0x81, 0x2, 0x95, 0x1, 0x75, |
| 0x3, 0x81, 0x1, 0x5, 0x1, 0x9, 0x30, 0x9, 0x31, 0x9, 0x38, 0x15, 0x81, 0x25, |
| 0x7f, 0x75, 0x8, 0x95, 0x3, 0x81, 0x6, 0xc0, 0xc0 |
| }; |
| |
| HidReportDescriptor GenerateReportDescriptor(const uint8_t raw_data[], |
| size_t size) { |
| HidReportDescriptor descriptor; |
| descriptor.size = size; |
| memcpy(&descriptor.data[0], &raw_data[0], size); |
| return descriptor; |
| } |
| |
| bool IsDeviceSafe(const std::vector<HidUsage>& usages) { |
| for (std::vector<HidUsage>::const_iterator iter = usages.begin(); |
| iter != usages.end(); ++iter) { |
| if (DenyUnsafeHidrawDeviceRule::IsUnsafeUsage(*iter)) |
| return false; |
| } |
| return true; |
| } |
| |
| } // namespace |
| |
| class DenyUnsafeHidrawDeviceRuleTest : public testing::Test { |
| public: |
| DenyUnsafeHidrawDeviceRuleTest() = default; |
| ~DenyUnsafeHidrawDeviceRuleTest() override = default; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(DenyUnsafeHidrawDeviceRuleTest); |
| }; |
| |
| TEST_F(DenyUnsafeHidrawDeviceRuleTest, IgnoreInvalidDescriptors) { |
| std::vector<HidUsage> usages; |
| ASSERT_FALSE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kInvalidDescriptor0), &usages)); |
| ASSERT_FALSE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kInvalidDescriptor1), &usages)); |
| ASSERT_FALSE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kInvalidDescriptor2), &usages)); |
| } |
| |
| TEST_F(DenyUnsafeHidrawDeviceRuleTest, IgnoreSafeDevices) { |
| std::vector<HidUsage> usages; |
| ASSERT_TRUE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kLUFATestFirmwareDescriptor), &usages)); |
| ASSERT_EQ(1u, usages.size()); |
| ASSERT_TRUE(IsDeviceSafe(usages)); |
| |
| usages.clear(); |
| ASSERT_TRUE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kLogitechG13Descriptor), &usages)); |
| ASSERT_EQ(1u, usages.size()); |
| ASSERT_TRUE(IsDeviceSafe(usages)); |
| } |
| |
| TEST_F(DenyUnsafeHidrawDeviceRuleTest, DenyKeyboardAccess) { |
| std::vector<HidUsage> usages; |
| ASSERT_TRUE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kSampleKeyboardDescriptor), &usages)); |
| ASSERT_EQ(1u, usages.size()); |
| ASSERT_FALSE(IsDeviceSafe(usages)); |
| } |
| |
| TEST_F(DenyUnsafeHidrawDeviceRuleTest, DenyMouseAccess) { |
| std::vector<HidUsage> usages; |
| ASSERT_TRUE( |
| HidrawSubsystemUdevRule::ParseToplevelCollectionUsages( |
| MAKE_DESCRIPTOR(kSampleMouseDescriptor), &usages)); |
| ASSERT_EQ(1u, usages.size()); |
| ASSERT_FALSE(IsDeviceSafe(usages)); |
| } |
| |
| } // namespace permission_broker |