github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/tools/syz-usbgen/usb_ids.patch (about)

     1  commit ea2ac1d4c7632717bac2410cfde8a2971aac65af
     2  Author: Andrey Konovalov <andreyknvl@gmail.com>
     3  Date:   Sun Aug 17 14:49:51 2025 +0000
     4  
     5      usb: dump USB and HID device IDs on HID enumeration
     6      
     7      Signed-off-by: Andrey Konovalov <andreyknvl@gmail.com>
     8  
     9  diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
    10  index b31b8a2fd..4893fcb4a 100644
    11  --- a/drivers/hid/hid-core.c
    12  +++ b/drivers/hid/hid-core.c
    13  @@ -27,6 +27,8 @@
    14   #include <linux/vmalloc.h>
    15   #include <linux/sched.h>
    16   #include <linux/semaphore.h>
    17  +#include <linux/usb.h>
    18  +#include "../usb/core/usb.h"
    19   
    20   #include <linux/hid.h>
    21   #include <linux/hiddev.h>
    22  @@ -2632,11 +2634,112 @@ static void hid_free_dynids(struct hid_driver *hdrv)
    23   	spin_unlock(&hdrv->dyn_lock);
    24   }
    25   
    26  +static void hid_device_id_dump_one(const struct hid_device_id *id, const char *driver_name)
    27  +{
    28  +	char buffer[128];
    29  +	int size = (char *)&id->product + sizeof(id->product) - (char *)id;
    30  +
    31  +	if (id->bus != HID_BUS_ANY && id->bus != BUS_USB)
    32  +		return;
    33  +
    34  +	bin2hex((char *)&buffer[0], (const char *)id, size);
    35  +	buffer[size * 2] = 0;
    36  +	pr_err("HIDID: %s (%s)\n", &buffer[0], driver_name);
    37  +}
    38  +
    39  +static void hid_device_id_dump_static(struct hid_driver *hdrv)
    40  +{
    41  +	const struct hid_device_id *id = hdrv->id_table;
    42  +
    43  +	for (; id->bus; id++)
    44  +		hid_device_id_dump_one(id, hdrv->name);
    45  +}
    46  +
    47  +static void hid_device_id_dump_dynamic(struct hid_driver *hdrv)
    48  +{
    49  +	struct hid_dynid *dynid;
    50  +
    51  +	spin_lock(&hdrv->dyn_lock);
    52  +	list_for_each_entry(dynid, &hdrv->dyn_list, list)
    53  +		hid_device_id_dump_one(&dynid->id, hdrv->name);
    54  +	spin_unlock(&hdrv->dyn_lock);
    55  +}
    56  +
    57  +static int hid_device_id_dump_driver(struct device_driver *drv, void *data)
    58  +{
    59  +	struct hid_driver *hdrv = to_hid_driver(drv);
    60  +
    61  +	hid_device_id_dump_static(hdrv);
    62  +	hid_device_id_dump_dynamic(hdrv);
    63  +
    64  +	return 0;
    65  +}
    66  +
    67  +static void usb_device_id_dump_one(const struct usb_device_id *id, const char *driver_name)
    68  +{
    69  +	char buffer[128];
    70  +	int size = (char *)&id->bInterfaceNumber + sizeof(id->bInterfaceNumber)
    71  +			- (char *)id;
    72  +
    73  +	bin2hex((char *)&buffer[0], (const char *)id, size);
    74  +	buffer[size * 2] = 0;
    75  +	pr_err("USBID: %s (%s)\n", &buffer[0], driver_name);
    76  +}
    77  +
    78  +static void usb_device_id_dump_static(struct usb_driver *drv)
    79  +{
    80  +	const struct usb_device_id *id = drv->id_table;
    81  +
    82  +	if (id == NULL)
    83  +		return;
    84  +
    85  +	for (; id->idVendor || id->idProduct || id->bDeviceClass ||
    86  +	       id->bInterfaceClass || id->driver_info; id++)
    87  +		usb_device_id_dump_one(id, drv->name);
    88  +}
    89  +
    90  +static void usb_device_id_dump_dynamic(struct usb_driver *drv)
    91  +{
    92  +	struct usb_dynid *dynid;
    93  +
    94  +	mutex_lock(&usb_dynids_lock);
    95  +	list_for_each_entry(dynid, &drv->dynids.list, node)
    96  +		usb_device_id_dump_one(&dynid->id, drv->name);
    97  +	mutex_unlock(&usb_dynids_lock);
    98  +}
    99  +
   100  +static int usb_device_id_dump_driver(struct device_driver *drv, void *data)
   101  +{
   102  +	struct usb_driver *usb_drv;
   103  +
   104  +	if (is_usb_device_driver(drv))
   105  +		return 0;
   106  +	usb_drv = to_usb_driver(drv);
   107  +
   108  +	usb_device_id_dump_static(usb_drv);
   109  +	usb_device_id_dump_dynamic(usb_drv);
   110  +
   111  +	return 0;
   112  +}
   113  +
   114  +static int usb_ids_dumped;
   115  +
   116  +static void usb_device_id_dump_all(void)
   117  +{
   118  +	if (usb_ids_dumped)
   119  +		return;
   120  +	usb_ids_dumped = 1;
   121  +	bus_for_each_drv(&usb_bus_type, NULL, NULL, usb_device_id_dump_driver);
   122  +	bus_for_each_drv(&hid_bus_type, NULL, NULL, hid_device_id_dump_driver);
   123  +}
   124  +
   125   const struct hid_device_id *hid_match_device(struct hid_device *hdev,
   126   					     struct hid_driver *hdrv)
   127   {
   128   	struct hid_dynid *dynid;
   129   
   130  +	usb_device_id_dump_all();
   131  +
   132   	spin_lock(&hdrv->dyn_lock);
   133   	list_for_each_entry(dynid, &hdrv->dyn_list, list) {
   134   		if (hid_match_one_id(hdev, &dynid->id)) {