mirror of
https://github.com/reactos/syzkaller.git
synced 2025-02-14 16:38:40 +00:00
![Andrey Konovalov](/assets/img/avatar_default.png)
* sys/linux: extract USB HID ids As it turns out the HID kernel subsystem registers only one USB driver that checks that the interface of the connected device has HID class and then looks up its own list of vendor/device ids to find a matching driver. This means that we currently don't generate proper vendor/device ids for USB HID devices. This patch updates the syz-usbgen tool to also extract USB HID vendor/device ids from a running kernel and makes the generated descriptions for HID devices to be patched using the extracted ids. This patch also contains some minor improvements to USB descriptions (better HID descriptions and more replies for some USB classes/drivers). * sys/linux: run make generate
111 lines
3.1 KiB
Diff
111 lines
3.1 KiB
Diff
commit 17edce0094c7d7b78b05748d5ce54d68d9bcb419
|
|
Author: Andrey Konovalov <andreyknvl@google.com>
|
|
Date: Wed Sep 27 17:06:15 2017 +0200
|
|
|
|
usb-fuzzer: dump usb device ids on enumeration
|
|
|
|
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
|
index 210b81a56e1a..6547515b8a2d 100644
|
|
--- a/drivers/hid/hid-core.c
|
|
+++ b/drivers/hid/hid-core.c
|
|
@@ -2114,11 +2114,45 @@ static void hid_free_dynids(struct hid_driver *hdrv)
|
|
spin_unlock(&hdrv->dyn_lock);
|
|
}
|
|
|
|
+static void hid_device_id_dump_one(const struct hid_device_id *id)
|
|
+{
|
|
+ char buffer[128];
|
|
+ int size = (char *)&id->product + sizeof(id->product) - (char *)id;
|
|
+
|
|
+ if (id->bus != HID_BUS_ANY && id->bus != BUS_USB)
|
|
+ return;
|
|
+
|
|
+ bin2hex((char *)&buffer[0], (const char *)id, size);
|
|
+ buffer[size * 2] = 0;
|
|
+ pr_err("HIDID: %s\n", &buffer[0]);
|
|
+}
|
|
+
|
|
+static void hid_device_id_dump_static(struct hid_driver *hdrv)
|
|
+{
|
|
+ const struct hid_device_id *id = hdrv->id_table;
|
|
+
|
|
+ for (; id->bus; id++)
|
|
+ hid_device_id_dump_one(id);
|
|
+}
|
|
+
|
|
+static void hid_device_id_dump_dynamic(struct hid_driver *hdrv)
|
|
+{
|
|
+ struct hid_dynid *dynid;
|
|
+
|
|
+ spin_lock(&hdrv->dyn_lock);
|
|
+ list_for_each_entry(dynid, &hdrv->dyn_list, list)
|
|
+ hid_device_id_dump_one(&dynid->id);
|
|
+ spin_unlock(&hdrv->dyn_lock);
|
|
+}
|
|
+
|
|
const struct hid_device_id *hid_match_device(struct hid_device *hdev,
|
|
struct hid_driver *hdrv)
|
|
{
|
|
struct hid_dynid *dynid;
|
|
|
|
+ hid_device_id_dump_static(hdrv);
|
|
+ hid_device_id_dump_dynamic(hdrv);
|
|
+
|
|
spin_lock(&hdrv->dyn_lock);
|
|
list_for_each_entry(dynid, &hdrv->dyn_list, list) {
|
|
if (hid_match_one_id(hdev, &dynid->id)) {
|
|
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
|
|
index ebcadaad89d1..44e2d797bb6a 100644
|
|
--- a/drivers/usb/core/driver.c
|
|
+++ b/drivers/usb/core/driver.c
|
|
@@ -790,6 +790,39 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
|
|
}
|
|
EXPORT_SYMBOL_GPL(usb_match_id);
|
|
|
|
+static void usb_device_id_dump_one(const struct usb_device_id *id)
|
|
+{
|
|
+ char buffer[128];
|
|
+ int size = (char *)&id->bInterfaceNumber + sizeof(id->bInterfaceNumber)
|
|
+ - (char *)id;
|
|
+
|
|
+ bin2hex((char *)&buffer[0], (const char *)id, size);
|
|
+ buffer[size * 2] = 0;
|
|
+ pr_err("USBID: %s\n", &buffer[0]);
|
|
+}
|
|
+
|
|
+static void usb_device_id_dump_static(struct usb_driver *drv)
|
|
+{
|
|
+ const struct usb_device_id *id = drv->id_table;
|
|
+
|
|
+ if (id == NULL)
|
|
+ return;
|
|
+
|
|
+ for (; id->idVendor || id->idProduct || id->bDeviceClass ||
|
|
+ id->bInterfaceClass || id->driver_info; id++)
|
|
+ usb_device_id_dump_one(id);
|
|
+}
|
|
+
|
|
+static void usb_device_id_dump_dynamic(struct usb_driver *drv)
|
|
+{
|
|
+ struct usb_dynid *dynid;
|
|
+
|
|
+ spin_lock(&drv->dynids.lock);
|
|
+ list_for_each_entry(dynid, &drv->dynids.list, node)
|
|
+ usb_device_id_dump_one(&dynid->id);
|
|
+ spin_unlock(&drv->dynids.lock);
|
|
+}
|
|
+
|
|
static int usb_device_match(struct device *dev, struct device_driver *drv)
|
|
{
|
|
/* devices and interfaces are handled separately */
|
|
@@ -814,6 +847,9 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
|
|
intf = to_usb_interface(dev);
|
|
usb_drv = to_usb_driver(drv);
|
|
|
|
+ usb_device_id_dump_static(usb_drv);
|
|
+ usb_device_id_dump_dynamic(usb_drv);
|
|
+
|
|
id = usb_match_id(intf, usb_drv->id_table);
|
|
if (id)
|
|
return 1;
|