[hid] Fix GetReport buffer overrun
Fix a potential buffer overrun in GetReport where
a malicious USB device could have a report size
greater than HID_MAX_REPORT_LEN.
Bug 50622: Fixed
Change-Id: I7cf36d004dcae7bdfffa5d1a355279fae7efe500
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/383179
Commit-Queue: David Gilhooley <dgilhooley@google.com>
Reviewed-by: Suraj Malhotra <surajmalhotra@google.com>
Reviewed-by: Andres Oportus <andresoportus@google.com>
Testability-Review: Suraj Malhotra <surajmalhotra@google.com>
Testability-Review: Andres Oportus <andresoportus@google.com>
diff --git a/src/ui/input/drivers/hid/hid-test.cc b/src/ui/input/drivers/hid/hid-test.cc
index 59be0e5..7da71a8 100644
--- a/src/ui/input/drivers/hid/hid-test.cc
+++ b/src/ui/input/drivers/hid/hid-test.cc
@@ -693,4 +693,37 @@
ASSERT_BYTES_EQ(&feature_report, &received_report, actual);
}
+// Tests that a device with too large reports don't cause buffer overruns.
+TEST_F(HidDeviceTest, GetReportBufferOverrun) {
+ const uint8_t desc[] = {
+ 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x02, // Usage (Mouse)
+ 0xA1, 0x01, // Collection (Application)
+ 0x05, 0x09, // Usage Page (Button)
+ 0x09, 0x30, // Usage (0x30)
+ 0x97, 0x00, 0xF0, 0x00, 0x00, // Report Count (65279)
+ 0x75, 0x08, // Report Size (8)
+ 0x25, 0x01, // Logical Maximum (1)
+ 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, // End Collection
+
+ // 22 bytes
+ };
+ size_t desc_size = sizeof(desc);
+ fake_hidbus_.SetDescriptor(desc, desc_size);
+
+ hid_info_t info = {};
+ info.device_class = HID_DEVICE_CLASS_OTHER;
+ info.boot_device = false;
+ fake_hidbus_.SetHidInfo(info);
+
+ ASSERT_OK(device_->Bind(fake_hidbus_.GetProto()));
+
+ std::vector<uint8_t> report(0xFF0000);
+ size_t actual;
+ ASSERT_EQ(
+ device_->HidDeviceGetReport(HID_REPORT_TYPE_INPUT, 0, report.data(), report.size(), &actual),
+ ZX_ERR_INTERNAL);
+}
+
} // namespace hid_driver
diff --git a/src/ui/input/drivers/hid/hid.cc b/src/ui/input/drivers/hid/hid.cc
index 95399cb..5224e08 100644
--- a/src/ui/input/drivers/hid/hid.cc
+++ b/src/ui/input/drivers/hid/hid.cc
@@ -303,6 +303,11 @@
if (needed > report_count) {
return ZX_ERR_BUFFER_TOO_SMALL;
}
+ if (needed > HID_MAX_REPORT_LEN) {
+ zxlogf(ERROR, "hid: GetReport: Report size 0x%lx larger than max size 0x%x", needed,
+ HID_MAX_REPORT_LEN);
+ return ZX_ERR_INTERNAL;
+ }
uint8_t report[HID_MAX_REPORT_LEN];
size_t actual = 0;