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

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