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)) {