blob: 4a28f72bfed825bc32ccc094f9eca843ae4f7262 [file] [log] [blame]
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;