blob: 90f4f91d73dd70dbcc804484a9df163c051b818e [file] [log] [blame]
// 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