| 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; |