| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/07 20:47 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"DVB_AS102",
"USB_PEGASUS",
"ATH9K_HTC",
"USB_XUSBATM",
"USB_TMC",
"USB_SERIAL_SPCP8X5"
],
"FocusSymbols": [
"usb_probe_interface",
"usb_device_match",
"as102_usb_probe",
"pegasus_probe",
"ath9k_hif_usb_probe",
"xusbatm_bind",
"usbtmc_probe",
"spcp8x5_probe",
"spcp8x5_port_probe"
],
"Reasoning": "The patch changes how dynamic IDs are matched in the USB core to prevent use-after-free bugs when drivers save the `usb_device_id` pointer passed to their `probe` functions. It modifies `usb_match_dynamic_id` to return a copy of the ID, and updates several USB drivers to extract the necessary information from `id-\u003edriver_info` during probe instead of storing the pointer. Fuzzing the USB core and the affected drivers (via dummy_hcd or raw-gadget) is necessary to ensure that the new dynamic ID matching logic and the driver probe functions work correctly and don't introduce regressions.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/07 20:47 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 320f4062aeed9a6453c74d177ae38961958c8bb1\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Jul 7 20:47:41 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c\nindex a11024451cebdc..be2f8be560fae2 100644\n--- a/drivers/media/usb/as102/as102_usb_drv.c\n+++ b/drivers/media/usb/as102/as102_usb_drv.c\n@@ -24,35 +24,33 @@ static void as102_usb_stop_stream(struct as102_dev_t *dev);\n static int as102_open(struct inode *inode, struct file *file);\n static int as102_release(struct inode *inode, struct file *file);\n \n-static const struct usb_device_id as102_usb_id_table[] = {\n-\t{ USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },\n-\t{ USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },\n-\t{ USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },\n-\t{ USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },\n-\t{ USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) },\n-\t{ } /* Terminating entry */\n+struct as102_dev_info {\n+\tconst char *name;\n+\t/*\n+\t * eLNA configuration: devices built on the reference design work best\n+\t * with 0xA0, while custom designs seem to require 0xC0\n+\t */\n+\tuint8_t elna_cfg;\n };\n \n-/* Note that this table must always have the same number of entries as the\n- as102_usb_id_table struct */\n-static const char * const as102_device_names[] = {\n-\tAS102_REFERENCE_DESIGN,\n-\tAS102_PCTV_74E,\n-\tAS102_ELGATO_EYETV_DTT_NAME,\n-\tAS102_NBOX_DVBT_DONGLE_NAME,\n-\tAS102_SKY_IT_DIGITAL_KEY_NAME,\n-\tNULL /* Terminating entry */\n-};\n+#define DRIVER_INFO(dev_name, dev_elna_cfg) \\\n+\t.driver_info = (kernel_ulong_t)\u0026(const struct as102_dev_info){ \\\n+\t\t.name = (dev_name), \\\n+\t\t.elna_cfg = (dev_elna_cfg), \\\n+\t}\n \n-/* eLNA configuration: devices built on the reference design work best\n- with 0xA0, while custom designs seem to require 0xC0 */\n-static uint8_t const as102_elna_cfg[] = {\n-\t0xA0,\n-\t0xC0,\n-\t0xC0,\n-\t0xA0,\n-\t0xA0,\n-\t0x00 /* Terminating entry */\n+static const struct usb_device_id as102_usb_id_table[] = {\n+\t{ USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001),\n+\t DRIVER_INFO(AS102_REFERENCE_DESIGN, 0xA0) },\n+\t{ USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID),\n+\t DRIVER_INFO(AS102_PCTV_74E, 0xC0) },\n+\t{ USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID),\n+\t DRIVER_INFO(AS102_ELGATO_EYETV_DTT_NAME, 0xC0) },\n+\t{ USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID),\n+\t DRIVER_INFO(AS102_NBOX_DVBT_DONGLE_NAME, 0xA0) },\n+\t{ USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID),\n+\t DRIVER_INFO(AS102_SKY_IT_DIGITAL_KEY_NAME, 0xA0) },\n+\t{ } /* Terminating entry */\n };\n \n struct usb_driver as102_usb_driver = {\n@@ -336,29 +334,18 @@ static int as102_usb_probe(struct usb_interface *intf,\n {\n \tint ret;\n \tstruct as102_dev_t *as102_dev;\n-\tint i;\n-\n-\t/* This should never actually happen */\n-\tif (ARRAY_SIZE(as102_usb_id_table) !=\n-\t (sizeof(as102_device_names) / sizeof(const char *))) {\n-\t\tpr_err(\"Device names table invalid size\");\n-\t\treturn -EINVAL;\n-\t}\n+\tconst struct as102_dev_info *info = (const struct as102_dev_info *)id-\u003edriver_info;\n \n \tas102_dev = kzalloc_obj(struct as102_dev_t);\n \tif (as102_dev == NULL)\n \t\treturn -ENOMEM;\n \n-\t/* Assign the user-friendly device name */\n-\tfor (i = 0; i \u003c ARRAY_SIZE(as102_usb_id_table); i++) {\n-\t\tif (id == \u0026as102_usb_id_table[i]) {\n-\t\t\tas102_dev-\u003ename = as102_device_names[i];\n-\t\t\tas102_dev-\u003eelna_cfg = as102_elna_cfg[i];\n-\t\t}\n-\t}\n-\n-\tif (as102_dev-\u003ename == NULL)\n+\tif (info) {\n+\t\tas102_dev-\u003ename = info-\u003ename;\n+\t\tas102_dev-\u003eelna_cfg = info-\u003eelna_cfg;\n+\t} else {\n \t\tas102_dev-\u003ename = \"Unknown AS102 device\";\n+\t}\n \n \t/* set private callback functions */\n \tas102_dev-\u003ebus_adap.ops = \u0026as102_priv_ops;\ndiff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c\nindex 8700eeb8e22d07..aba1a640fc2688 100644\n--- a/drivers/net/usb/pegasus.c\n+++ b/drivers/net/usb/pegasus.c\n@@ -43,21 +43,12 @@ static bool loopback;\n static bool mii_mode;\n static char *devid;\n \n-static struct usb_eth_dev usb_dev_id[] = {\n-#define\tPEGASUS_DEV(pn, vid, pid, flags)\t\\\n-\t{.name = pn, .vendor = vid, .device = pid, .private = flags},\n-#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \\\n-\tPEGASUS_DEV(pn, vid, pid, flags)\n-#include \"pegasus.h\"\n-#undef\tPEGASUS_DEV\n-#undef\tPEGASUS_DEV_CLASS\n-\t{NULL, 0, 0, 0},\n-\t{NULL, 0, 0, 0}\n-};\n+static struct usb_eth_dev dynamic_id_info = {};\n \n static struct usb_device_id pegasus_ids[] = {\n #define\tPEGASUS_DEV(pn, vid, pid, flags) \\\n-\t{.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},\n+\t{.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid, \\\n+\t .driver_info = (kernel_ulong_t)\u0026(const struct usb_eth_dev) {.name = pn, .private = flags}},\n /*\n * The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product\n * IDs as the Belkin F5D5050, so we need to teach the pegasus driver to\n@@ -66,7 +57,8 @@ static struct usb_device_id pegasus_ids[] = {\n */\n #define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \\\n \t{.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \\\n-\t.idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},\n+\t.idVendor = vid, .idProduct = pid, .bDeviceClass = dclass, \\\n+\t.driver_info = (kernel_ulong_t)\u0026(const struct usb_eth_dev) {.name = pn, .private = flags}},\n #include \"pegasus.h\"\n #undef\tPEGASUS_DEV\n #undef\tPEGASUS_DEV_CLASS\n@@ -402,12 +394,12 @@ static inline int reset_mac(pegasus_t *pegasus)\n \tif (i == REG_TIMEOUT)\n \t\treturn -ETIMEDOUT;\n \n-\tif (usb_dev_id[pegasus-\u003edev_index].vendor == VENDOR_LINKSYS ||\n-\t usb_dev_id[pegasus-\u003edev_index].vendor == VENDOR_DLINK) {\n+\tif (le16_to_cpu(pegasus-\u003eusb-\u003edescriptor.idVendor) == VENDOR_LINKSYS ||\n+\t le16_to_cpu(pegasus-\u003eusb-\u003edescriptor.idVendor) == VENDOR_DLINK) {\n \t\tset_register(pegasus, Gpio0, 0x24);\n \t\tset_register(pegasus, Gpio0, 0x26);\n \t}\n-\tif (usb_dev_id[pegasus-\u003edev_index].vendor == VENDOR_ELCON) {\n+\tif (le16_to_cpu(pegasus-\u003eusb-\u003edescriptor.idVendor) == VENDOR_ELCON) {\n \t\t__u16 auxmode;\n \t\tret = read_mii_word(pegasus, 3, 0x1b, \u0026auxmode);\n \t\tif (ret \u003c 0)\n@@ -445,9 +437,9 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)\n \tmemcpy(pegasus-\u003eeth_regs, data, sizeof(data));\n \tret = set_registers(pegasus, EthCtrl0, 3, data);\n \n-\tif (usb_dev_id[pegasus-\u003edev_index].vendor == VENDOR_LINKSYS ||\n-\t usb_dev_id[pegasus-\u003edev_index].vendor == VENDOR_LINKSYS2 ||\n-\t usb_dev_id[pegasus-\u003edev_index].vendor == VENDOR_DLINK) {\n+\tif (le16_to_cpu(pegasus-\u003eusb-\u003edescriptor.idVendor) == VENDOR_LINKSYS ||\n+\t le16_to_cpu(pegasus-\u003eusb-\u003edescriptor.idVendor) == VENDOR_LINKSYS2 ||\n+\t le16_to_cpu(pegasus-\u003eusb-\u003edescriptor.idVendor) == VENDOR_DLINK) {\n \t\tu16 auxmode;\n \t\tret = read_mii_word(pegasus, 0, 0x1b, \u0026auxmode);\n \t\tif (ret \u003c 0)\n@@ -1153,7 +1145,7 @@ static int pegasus_probe(struct usb_interface *intf,\n \tstruct usb_device *dev = interface_to_usbdev(intf);\n \tstruct net_device *net;\n \tpegasus_t *pegasus;\n-\tint dev_index = id - pegasus_ids;\n+\tconst struct usb_eth_dev *info = (const struct usb_eth_dev *)id-\u003edriver_info;\n \tint res = -ENOMEM;\n \tstatic const u8 bulk_ep_addr[] = {\n \t\tPEGASUS_USB_EP_BULK_IN | USB_DIR_IN,\n@@ -1178,7 +1170,6 @@ static int pegasus_probe(struct usb_interface *intf,\n \t\tgoto out;\n \n \tpegasus = netdev_priv(net);\n-\tpegasus-\u003edev_index = dev_index;\n \tpegasus-\u003eintf = intf;\n \n \tres = alloc_urbs(pegasus);\n@@ -1206,7 +1197,7 @@ static int pegasus_probe(struct usb_interface *intf,\n \tpegasus-\u003emsg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV\n \t\t\t\t| NETIF_MSG_PROBE | NETIF_MSG_LINK);\n \n-\tpegasus-\u003efeatures = usb_dev_id[dev_index].private;\n+\tpegasus-\u003efeatures = info ? info-\u003eprivate : DEFAULT_GPIO_RESET;\n \tres = get_interrupt_interval(pegasus);\n \tif (res)\n \t\tgoto out2;\n@@ -1235,7 +1226,7 @@ static int pegasus_probe(struct usb_interface *intf,\n \tqueue_delayed_work(system_long_wq, \u0026pegasus-\u003ecarrier_check,\n \t\t\t CARRIER_CHECK_DELAY);\n \tdev_info(\u0026intf-\u003edev, \"%s, %s, %pM\\n\", net-\u003ename,\n-\t\t usb_dev_id[dev_index].name, net-\u003edev_addr);\n+\t\t info ? info-\u003ename : \"(unknown)\", net-\u003edev_addr);\n \treturn 0;\n \n out3:\n@@ -1325,8 +1316,9 @@ static struct usb_driver pegasus_driver = {\n \n static void __init parse_id(char *id)\n {\n-\tunsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0;\n+\tunsigned int vendor_id = 0, device_id = 0, flags = 0;\n \tchar *token, *name = NULL;\n+\tint dyn_id_index = ARRAY_SIZE(pegasus_ids) - 2;\n \n \ttoken = strsep(\u0026id, \":\");\n \tif (token)\n@@ -1348,14 +1340,12 @@ static void __init parse_id(char *id)\n \tif (device_id \u003e 0x10000 || device_id == 0)\n \t\treturn;\n \n-\tfor (i = 0; usb_dev_id[i].name; i++);\n-\tusb_dev_id[i].name = name;\n-\tusb_dev_id[i].vendor = vendor_id;\n-\tusb_dev_id[i].device = device_id;\n-\tusb_dev_id[i].private = flags;\n-\tpegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;\n-\tpegasus_ids[i].idVendor = vendor_id;\n-\tpegasus_ids[i].idProduct = device_id;\n+\tdynamic_id_info.name = name;\n+\tdynamic_id_info.private = flags;\n+\tpegasus_ids[dyn_id_index].match_flags = USB_DEVICE_ID_MATCH_DEVICE;\n+\tpegasus_ids[dyn_id_index].idVendor = vendor_id;\n+\tpegasus_ids[dyn_id_index].idProduct = device_id;\n+\tpegasus_ids[dyn_id_index].driver_info = (kernel_ulong_t)\u0026dynamic_id_info;\n }\n \n static int __init pegasus_init(void)\ndiff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h\nindex a05b143155ba86..ccdedcef52e76e 100644\n--- a/drivers/net/usb/pegasus.h\n+++ b/drivers/net/usb/pegasus.h\n@@ -85,7 +85,6 @@ typedef struct pegasus {\n \tunsigned\t\tfeatures;\n \tu32\t\t\tmsg_enable;\n \tu32\t\t\twolopts;\n-\tint\t\t\tdev_index;\n \tint\t\t\tintr_interval;\n \tstruct tasklet_struct\trx_tl;\n \tstruct delayed_work\tcarrier_check;\n@@ -102,8 +101,6 @@ typedef struct pegasus {\n \n struct usb_eth_dev {\n \tchar\t*name;\n-\t__u16\tvendor;\n-\t__u16\tdevice;\n \t__u32\tprivate; /* LSB is gpio reset value */\n };\n \ndiff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c\nindex 47f904e7e65297..d3491ff08e6ef5 100644\n--- a/drivers/net/wireless/ath/ath9k/hif_usb.c\n+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c\n@@ -1087,7 +1087,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)\n \t}\n \tkfree(buf);\n \n-\tif (IS_AR7010_DEVICE(hif_dev-\u003eusb_device_id-\u003edriver_info))\n+\tif (IS_AR7010_DEVICE(hif_dev-\u003eid_info))\n \t\tfirm_offset = AR7010_FIRMWARE_TEXT;\n \telse\n \t\tfirm_offset = AR9271_FIRMWARE_TEXT;\n@@ -1182,7 +1182,7 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,\n \tif (MAJOR_VERSION_REQ == 1 \u0026\u0026 hif_dev-\u003efw_minor_index == 3) {\n \t\tconst char *filename;\n \n-\t\tif (IS_AR7010_DEVICE(hif_dev-\u003eusb_device_id-\u003edriver_info))\n+\t\tif (IS_AR7010_DEVICE(hif_dev-\u003eid_info))\n \t\t\tfilename = FIRMWARE_AR7010_1_1;\n \t\telse\n \t\t\tfilename = FIRMWARE_AR9271;\n@@ -1198,7 +1198,7 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,\n \n \t\treturn -ENOENT;\n \t} else {\n-\t\tif (IS_AR7010_DEVICE(hif_dev-\u003eusb_device_id-\u003edriver_info))\n+\t\tif (IS_AR7010_DEVICE(hif_dev-\u003eid_info))\n \t\t\tchip = \"7010\";\n \t\telse\n \t\t\tchip = \"9271\";\n@@ -1255,9 +1255,9 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)\n \n \tret = ath9k_htc_hw_init(hif_dev-\u003ehtc_handle,\n \t\t\t\t\u0026hif_dev-\u003einterface-\u003edev,\n-\t\t\t\thif_dev-\u003eusb_device_id-\u003eidProduct,\n+\t\t\t\tle16_to_cpu(hif_dev-\u003eudev-\u003edescriptor.idProduct),\n \t\t\t\thif_dev-\u003eudev-\u003eproduct,\n-\t\t\t\thif_dev-\u003eusb_device_id-\u003edriver_info);\n+\t\t\t\thif_dev-\u003eid_info);\n \tif (ret) {\n \t\tret = -EINVAL;\n \t\tgoto err_htc_hw_init;\n@@ -1369,7 +1369,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,\n \n \thif_dev-\u003eudev = udev;\n \thif_dev-\u003einterface = interface;\n-\thif_dev-\u003eusb_device_id = id;\n+\thif_dev-\u003eid_info = id-\u003edriver_info;\n #ifdef CONFIG_PM\n \tudev-\u003ereset_resume = 1;\n #endif\ndiff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h\nindex dc0b0fa5c32574..b3e7b0fb54b841 100644\n--- a/drivers/net/wireless/ath/ath9k/hif_usb.h\n+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h\n@@ -115,7 +115,7 @@ struct cmd_buf {\n struct hif_device_usb {\n \tstruct usb_device *udev;\n \tstruct usb_interface *interface;\n-\tconst struct usb_device_id *usb_device_id;\n+\tint id_info;\n \tconst void *fw_data;\n \tsize_t fw_size;\n \tstruct completion fw_done;\ndiff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c\nindex 0befbf63d1cc83..5c1e1f52155558 100644\n--- a/drivers/usb/atm/xusbatm.c\n+++ b/drivers/usb/atm/xusbatm.c\n@@ -79,7 +79,7 @@ static int xusbatm_bind(struct usbatm_data *usbatm,\n \t\t\tstruct usb_interface *intf, const struct usb_device_id *id)\n {\n \tstruct usb_device *usb_dev = interface_to_usbdev(intf);\n-\tint drv_ix = id - xusbatm_usb_ids;\n+\tint drv_ix = id-\u003edriver_info;\n \tint rx_alt = rx_altsetting[drv_ix];\n \tint tx_alt = tx_altsetting[drv_ix];\n \tstruct usb_interface *rx_intf = xusbatm_find_intf(usb_dev, rx_alt, rx_endpoint[drv_ix]);\n@@ -168,7 +168,8 @@ static struct usb_driver xusbatm_usb_driver = {\n \t.name\t\t= xusbatm_driver_name,\n \t.probe\t\t= xusbatm_usb_probe,\n \t.disconnect\t= usbatm_usb_disconnect,\n-\t.id_table\t= xusbatm_usb_ids\n+\t.id_table\t= xusbatm_usb_ids,\n+\t.no_dynamic_id\t= 1,\n };\n \n static int __init xusbatm_init(void)\n@@ -190,6 +191,7 @@ static int __init xusbatm_init(void)\n \t\txusbatm_usb_ids[i].match_flags\t= USB_DEVICE_ID_MATCH_DEVICE;\n \t\txusbatm_usb_ids[i].idVendor\t= vendor[i];\n \t\txusbatm_usb_ids[i].idProduct\t= product[i];\n+\t\txusbatm_usb_ids[i].driver_info\t= i;\n \n \t\txusbatm_drivers[i].driver_name\t= xusbatm_driver_name;\n \t\txusbatm_drivers[i].bind\t\t= xusbatm_bind;\ndiff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c\nindex af9ae55dae14e0..51cd9320a7366a 100644\n--- a/drivers/usb/class/usbtmc.c\n+++ b/drivers/usb/class/usbtmc.c\n@@ -71,7 +71,6 @@ struct usbtmc_dev_capabilities {\n * allocated for each USBTMC device in the driver's probe function.\n */\n struct usbtmc_device_data {\n-\tconst struct usb_device_id *id;\n \tstruct usb_device *usb_dev;\n \tstruct usb_interface *intf;\n \tstruct list_head file_list;\n@@ -2394,7 +2393,6 @@ static int usbtmc_probe(struct usb_interface *intf,\n \t\treturn -ENOMEM;\n \n \tdata-\u003eintf = intf;\n-\tdata-\u003eid = id;\n \tdata-\u003eusb_dev = usb_get_dev(interface_to_usbdev(intf));\n \tusb_set_intfdata(intf, data);\n \tkref_init(\u0026data-\u003ekref);\ndiff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c\nindex f63004417058e6..7f33fe5ba03bde 100644\n--- a/drivers/usb/core/driver.c\n+++ b/drivers/usb/core/driver.c\n@@ -228,14 +228,16 @@ static void usb_free_dynids(struct usb_driver *usb_drv)\n }\n \n static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,\n-\t\t\t\t\t\t\tconst struct usb_driver *drv)\n+\t\t\t\t\t\t\tconst struct usb_driver *drv,\n+\t\t\t\t\t\t\tstruct usb_device_id *id_copy)\n {\n \tstruct usb_dynid *dynid;\n \n \tguard(mutex)(\u0026usb_dynids_lock);\n \tlist_for_each_entry(dynid, \u0026drv-\u003edynids.list, node) {\n \t\tif (usb_match_one_id(intf, \u0026dynid-\u003eid)) {\n-\t\t\treturn \u0026dynid-\u003eid;\n+\t\t\t*id_copy = dynid-\u003eid;\n+\t\t\treturn id_copy;\n \t\t}\n \t}\n \treturn NULL;\n@@ -321,6 +323,7 @@ static int usb_probe_interface(struct device *dev)\n \tstruct usb_interface *intf = to_usb_interface(dev);\n \tstruct usb_device *udev = interface_to_usbdev(intf);\n \tconst struct usb_device_id *id;\n+\tstruct usb_device_id id_copy;\n \tint error = -ENODEV;\n \tint lpm_disable_error = -ENODEV;\n \n@@ -340,7 +343,7 @@ static int usb_probe_interface(struct device *dev)\n \t\treturn error;\n \t}\n \n-\tid = usb_match_dynamic_id(intf, driver);\n+\tid = usb_match_dynamic_id(intf, driver, \u0026id_copy);\n \tif (!id)\n \t\tid = usb_match_id(intf, driver-\u003eid_table);\n \tif (!id)\n@@ -892,6 +895,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv)\n \t\tstruct usb_interface *intf;\n \t\tconst struct usb_driver *usb_drv;\n \t\tconst struct usb_device_id *id;\n+\t\tstruct usb_device_id id_copy;\n \n \t\t/* device drivers never match interfaces */\n \t\tif (is_usb_device_driver(drv))\n@@ -904,7 +908,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv)\n \t\tif (id)\n \t\t\treturn 1;\n \n-\t\tid = usb_match_dynamic_id(intf, usb_drv);\n+\t\tid = usb_match_dynamic_id(intf, usb_drv, \u0026id_copy);\n \t\tif (id)\n \t\t\treturn 1;\n \t}\ndiff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c\nindex c11d64bf08fbae..0e7715a02df4cc 100644\n--- a/drivers/usb/serial/spcp8x5.c\n+++ b/drivers/usb/serial/spcp8x5.c\n@@ -133,14 +133,14 @@ struct spcp8x5_private {\n static int spcp8x5_probe(struct usb_serial *serial,\n \t\t\t\t\t\tconst struct usb_device_id *id)\n {\n-\tusb_set_serial_data(serial, (void *)id);\n+\tusb_set_serial_data(serial, (void *)id-\u003edriver_info);\n \n \treturn 0;\n }\n \n static int spcp8x5_port_probe(struct usb_serial_port *port)\n {\n-\tconst struct usb_device_id *id = usb_get_serial_data(port-\u003eserial);\n+\tunsigned int quirks = (unsigned int)(unsigned long)usb_get_serial_data(port-\u003eserial);\n \tstruct spcp8x5_private *priv;\n \n \tpriv = kzalloc_obj(*priv);\n@@ -148,7 +148,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port)\n \t\treturn -ENOMEM;\n \n \tspin_lock_init(\u0026priv-\u003elock);\n-\tpriv-\u003equirks = id-\u003edriver_info;\n+\tpriv-\u003equirks = quirks;\n \n \tusb_set_serial_port_data(port, priv);\n \ndiff --git a/include/linux/usb.h b/include/linux/usb.h\nindex 1da4ad1610bca0..49ab8dbb885f65 100644\n--- a/include/linux/usb.h\n+++ b/include/linux/usb.h\n@@ -1185,7 +1185,8 @@ extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf);\n *\tinterface. It may also use usb_set_interface() to specify the\n *\tappropriate altsetting. If unwilling to manage the interface,\n *\treturn -ENODEV, if genuine IO errors occurred, an appropriate\n- *\tnegative errno value.\n+ *\tnegative errno value. The usb_device_id parameter is only valid during\n+ *\tprobe.\n * @disconnect: Called when the interface is no longer accessible, usually\n *\tbecause its device has been (or is being) disconnected or the\n *\tdriver module is being unloaded.\n"
} |
| 2/1 | 2026/07/07 20:47 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"DVB_AS102",
"USB_PEGASUS",
"ATH9K_HTC",
"USB_XUSBATM",
"USB_TMC",
"USB_SERIAL_SPCP8X5"
],
"FocusSymbols": [
"usb_probe_interface",
"usb_device_match",
"as102_usb_probe",
"pegasus_probe",
"ath9k_hif_usb_probe",
"xusbatm_bind",
"usbtmc_probe",
"spcp8x5_probe",
"spcp8x5_port_probe"
],
"Reasoning": "The patch changes how dynamic IDs are matched in the USB core to prevent use-after-free bugs when drivers save the `usb_device_id` pointer passed to their `probe` functions. It modifies `usb_match_dynamic_id` to return a copy of the ID, and updates several USB drivers to extract the necessary information from `id-\u003edriver_info` during probe instead of storing the pointer. Fuzzing the USB core and the affected drivers (via dummy_hcd or raw-gadget) is necessary to ensure that the new dynamic ID matching logic and the driver probe functions work correctly and don't introduce regressions.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 320f4062aeed9a6453c74d177ae38961958c8bb1
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Jul 7 20:47:41 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c
index a11024451cebdc..be2f8be560fae2 100644
--- a/drivers/media/usb/as102/as102_usb_drv.c
+++ b/drivers/media/usb/as102/as102_usb_drv.c
@@ -24,35 +24,33 @@ static void as102_usb_stop_stream(struct as102_dev_t *dev);
static int as102_open(struct inode *inode, struct file *file);
static int as102_release(struct inode *inode, struct file *file);
-static const struct usb_device_id as102_usb_id_table[] = {
- { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
- { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
- { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
- { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
- { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) },
- { } /* Terminating entry */
+struct as102_dev_info {
+ const char *name;
+ /*
+ * eLNA configuration: devices built on the reference design work best
+ * with 0xA0, while custom designs seem to require 0xC0
+ */
+ uint8_t elna_cfg;
};
-/* Note that this table must always have the same number of entries as the
- as102_usb_id_table struct */
-static const char * const as102_device_names[] = {
- AS102_REFERENCE_DESIGN,
- AS102_PCTV_74E,
- AS102_ELGATO_EYETV_DTT_NAME,
- AS102_NBOX_DVBT_DONGLE_NAME,
- AS102_SKY_IT_DIGITAL_KEY_NAME,
- NULL /* Terminating entry */
-};
+#define DRIVER_INFO(dev_name, dev_elna_cfg) \
+ .driver_info = (kernel_ulong_t)&(const struct as102_dev_info){ \
+ .name = (dev_name), \
+ .elna_cfg = (dev_elna_cfg), \
+ }
-/* eLNA configuration: devices built on the reference design work best
- with 0xA0, while custom designs seem to require 0xC0 */
-static uint8_t const as102_elna_cfg[] = {
- 0xA0,
- 0xC0,
- 0xC0,
- 0xA0,
- 0xA0,
- 0x00 /* Terminating entry */
+static const struct usb_device_id as102_usb_id_table[] = {
+ { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001),
+ DRIVER_INFO(AS102_REFERENCE_DESIGN, 0xA0) },
+ { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID),
+ DRIVER_INFO(AS102_PCTV_74E, 0xC0) },
+ { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID),
+ DRIVER_INFO(AS102_ELGATO_EYETV_DTT_NAME, 0xC0) },
+ { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID),
+ DRIVER_INFO(AS102_NBOX_DVBT_DONGLE_NAME, 0xA0) },
+ { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID),
+ DRIVER_INFO(AS102_SKY_IT_DIGITAL_KEY_NAME, 0xA0) },
+ { } /* Terminating entry */
};
struct usb_driver as102_usb_driver = {
@@ -336,29 +334,18 @@ static int as102_usb_probe(struct usb_interface *intf,
{
int ret;
struct as102_dev_t *as102_dev;
- int i;
-
- /* This should never actually happen */
- if (ARRAY_SIZE(as102_usb_id_table) !=
- (sizeof(as102_device_names) / sizeof(const char *))) {
- pr_err("Device names table invalid size");
- return -EINVAL;
- }
+ const struct as102_dev_info *info = (const struct as102_dev_info *)id->driver_info;
as102_dev = kzalloc_obj(struct as102_dev_t);
if (as102_dev == NULL)
return -ENOMEM;
- /* Assign the user-friendly device name */
- for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) {
- if (id == &as102_usb_id_table[i]) {
- as102_dev->name = as102_device_names[i];
- as102_dev->elna_cfg = as102_elna_cfg[i];
- }
- }
-
- if (as102_dev->name == NULL)
+ if (info) {
+ as102_dev->name = info->name;
+ as102_dev->elna_cfg = info->elna_cfg;
+ } else {
as102_dev->name = "Unknown AS102 device";
+ }
/* set private callback functions */
as102_dev->bus_adap.ops = &as102_priv_ops;
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 8700eeb8e22d07..aba1a640fc2688 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -43,21 +43,12 @@ static bool loopback;
static bool mii_mode;
static char *devid;
-static struct usb_eth_dev usb_dev_id[] = {
-#define PEGASUS_DEV(pn, vid, pid, flags) \
- {.name = pn, .vendor = vid, .device = pid, .private = flags},
-#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
- PEGASUS_DEV(pn, vid, pid, flags)
-#include "pegasus.h"
-#undef PEGASUS_DEV
-#undef PEGASUS_DEV_CLASS
- {NULL, 0, 0, 0},
- {NULL, 0, 0, 0}
-};
+static struct usb_eth_dev dynamic_id_info = {};
static struct usb_device_id pegasus_ids[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \
- {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
+ {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid, \
+ .driver_info = (kernel_ulong_t)&(const struct usb_eth_dev) {.name = pn, .private = flags}},
/*
* The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
* IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
@@ -66,7 +57,8 @@ static struct usb_device_id pegasus_ids[] = {
*/
#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
{.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
- .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
+ .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass, \
+ .driver_info = (kernel_ulong_t)&(const struct usb_eth_dev) {.name = pn, .private = flags}},
#include "pegasus.h"
#undef PEGASUS_DEV
#undef PEGASUS_DEV_CLASS
@@ -402,12 +394,12 @@ static inline int reset_mac(pegasus_t *pegasus)
if (i == REG_TIMEOUT)
return -ETIMEDOUT;
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
+ if (le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_LINKSYS ||
+ le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_DLINK) {
set_register(pegasus, Gpio0, 0x24);
set_register(pegasus, Gpio0, 0x26);
}
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
+ if (le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_ELCON) {
__u16 auxmode;
ret = read_mii_word(pegasus, 3, 0x1b, &auxmode);
if (ret < 0)
@@ -445,9 +437,9 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
memcpy(pegasus->eth_regs, data, sizeof(data));
ret = set_registers(pegasus, EthCtrl0, 3, data);
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
+ if (le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_LINKSYS ||
+ le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_LINKSYS2 ||
+ le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_DLINK) {
u16 auxmode;
ret = read_mii_word(pegasus, 0, 0x1b, &auxmode);
if (ret < 0)
@@ -1153,7 +1145,7 @@ static int pegasus_probe(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev(intf);
struct net_device *net;
pegasus_t *pegasus;
- int dev_index = id - pegasus_ids;
+ const struct usb_eth_dev *info = (const struct usb_eth_dev *)id->driver_info;
int res = -ENOMEM;
static const u8 bulk_ep_addr[] = {
PEGASUS_USB_EP_BULK_IN | USB_DIR_IN,
@@ -1178,7 +1170,6 @@ static int pegasus_probe(struct usb_interface *intf,
goto out;
pegasus = netdev_priv(net);
- pegasus->dev_index = dev_index;
pegasus->intf = intf;
res = alloc_urbs(pegasus);
@@ -1206,7 +1197,7 @@ static int pegasus_probe(struct usb_interface *intf,
pegasus->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
| NETIF_MSG_PROBE | NETIF_MSG_LINK);
- pegasus->features = usb_dev_id[dev_index].private;
+ pegasus->features = info ? info->private : DEFAULT_GPIO_RESET;
res = get_interrupt_interval(pegasus);
if (res)
goto out2;
@@ -1235,7 +1226,7 @@ static int pegasus_probe(struct usb_interface *intf,
queue_delayed_work(system_long_wq, &pegasus->carrier_check,
CARRIER_CHECK_DELAY);
dev_info(&intf->dev, "%s, %s, %pM\n", net->name,
- usb_dev_id[dev_index].name, net->dev_addr);
+ info ? info->name : "(unknown)", net->dev_addr);
return 0;
out3:
@@ -1325,8 +1316,9 @@ static struct usb_driver pegasus_driver = {
static void __init parse_id(char *id)
{
- unsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0;
+ unsigned int vendor_id = 0, device_id = 0, flags = 0;
char *token, *name = NULL;
+ int dyn_id_index = ARRAY_SIZE(pegasus_ids) - 2;
token = strsep(&id, ":");
if (token)
@@ -1348,14 +1340,12 @@ static void __init parse_id(char *id)
if (device_id > 0x10000 || device_id == 0)
return;
- for (i = 0; usb_dev_id[i].name; i++);
- usb_dev_id[i].name = name;
- usb_dev_id[i].vendor = vendor_id;
- usb_dev_id[i].device = device_id;
- usb_dev_id[i].private = flags;
- pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
- pegasus_ids[i].idVendor = vendor_id;
- pegasus_ids[i].idProduct = device_id;
+ dynamic_id_info.name = name;
+ dynamic_id_info.private = flags;
+ pegasus_ids[dyn_id_index].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ pegasus_ids[dyn_id_index].idVendor = vendor_id;
+ pegasus_ids[dyn_id_index].idProduct = device_id;
+ pegasus_ids[dyn_id_index].driver_info = (kernel_ulong_t)&dynamic_id_info;
}
static int __init pegasus_init(void)
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index a05b143155ba86..ccdedcef52e76e 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -85,7 +85,6 @@ typedef struct pegasus {
unsigned features;
u32 msg_enable;
u32 wolopts;
- int dev_index;
int intr_interval;
struct tasklet_struct rx_tl;
struct delayed_work carrier_check;
@@ -102,8 +101,6 @@ typedef struct pegasus {
struct usb_eth_dev {
char *name;
- __u16 vendor;
- __u16 device;
__u32 private; /* LSB is gpio reset value */
};
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 47f904e7e65297..d3491ff08e6ef5 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1087,7 +1087,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
}
kfree(buf);
- if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
+ if (IS_AR7010_DEVICE(hif_dev->id_info))
firm_offset = AR7010_FIRMWARE_TEXT;
else
firm_offset = AR9271_FIRMWARE_TEXT;
@@ -1182,7 +1182,7 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,
if (MAJOR_VERSION_REQ == 1 && hif_dev->fw_minor_index == 3) {
const char *filename;
- if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
+ if (IS_AR7010_DEVICE(hif_dev->id_info))
filename = FIRMWARE_AR7010_1_1;
else
filename = FIRMWARE_AR9271;
@@ -1198,7 +1198,7 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,
return -ENOENT;
} else {
- if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
+ if (IS_AR7010_DEVICE(hif_dev->id_info))
chip = "7010";
else
chip = "9271";
@@ -1255,9 +1255,9 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
&hif_dev->interface->dev,
- hif_dev->usb_device_id->idProduct,
+ le16_to_cpu(hif_dev->udev->descriptor.idProduct),
hif_dev->udev->product,
- hif_dev->usb_device_id->driver_info);
+ hif_dev->id_info);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
@@ -1369,7 +1369,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
hif_dev->udev = udev;
hif_dev->interface = interface;
- hif_dev->usb_device_id = id;
+ hif_dev->id_info = id->driver_info;
#ifdef CONFIG_PM
udev->reset_resume = 1;
#endif
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index dc0b0fa5c32574..b3e7b0fb54b841 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -115,7 +115,7 @@ struct cmd_buf {
struct hif_device_usb {
struct usb_device *udev;
struct usb_interface *interface;
- const struct usb_device_id *usb_device_id;
+ int id_info;
const void *fw_data;
size_t fw_size;
struct completion fw_done;
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 0befbf63d1cc83..5c1e1f52155558 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -79,7 +79,7 @@ static int xusbatm_bind(struct usbatm_data *usbatm,
struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *usb_dev = interface_to_usbdev(intf);
- int drv_ix = id - xusbatm_usb_ids;
+ int drv_ix = id->driver_info;
int rx_alt = rx_altsetting[drv_ix];
int tx_alt = tx_altsetting[drv_ix];
struct usb_interface *rx_intf = xusbatm_find_intf(usb_dev, rx_alt, rx_endpoint[drv_ix]);
@@ -168,7 +168,8 @@ static struct usb_driver xusbatm_usb_driver = {
.name = xusbatm_driver_name,
.probe = xusbatm_usb_probe,
.disconnect = usbatm_usb_disconnect,
- .id_table = xusbatm_usb_ids
+ .id_table = xusbatm_usb_ids,
+ .no_dynamic_id = 1,
};
static int __init xusbatm_init(void)
@@ -190,6 +191,7 @@ static int __init xusbatm_init(void)
xusbatm_usb_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
xusbatm_usb_ids[i].idVendor = vendor[i];
xusbatm_usb_ids[i].idProduct = product[i];
+ xusbatm_usb_ids[i].driver_info = i;
xusbatm_drivers[i].driver_name = xusbatm_driver_name;
xusbatm_drivers[i].bind = xusbatm_bind;
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index af9ae55dae14e0..51cd9320a7366a 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -71,7 +71,6 @@ struct usbtmc_dev_capabilities {
* allocated for each USBTMC device in the driver's probe function.
*/
struct usbtmc_device_data {
- const struct usb_device_id *id;
struct usb_device *usb_dev;
struct usb_interface *intf;
struct list_head file_list;
@@ -2394,7 +2393,6 @@ static int usbtmc_probe(struct usb_interface *intf,
return -ENOMEM;
data->intf = intf;
- data->id = id;
data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
usb_set_intfdata(intf, data);
kref_init(&data->kref);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f63004417058e6..7f33fe5ba03bde 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -228,14 +228,16 @@ static void usb_free_dynids(struct usb_driver *usb_drv)
}
static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
- const struct usb_driver *drv)
+ const struct usb_driver *drv,
+ struct usb_device_id *id_copy)
{
struct usb_dynid *dynid;
guard(mutex)(&usb_dynids_lock);
list_for_each_entry(dynid, &drv->dynids.list, node) {
if (usb_match_one_id(intf, &dynid->id)) {
- return &dynid->id;
+ *id_copy = dynid->id;
+ return id_copy;
}
}
return NULL;
@@ -321,6 +323,7 @@ static int usb_probe_interface(struct device *dev)
struct usb_interface *intf = to_usb_interface(dev);
struct usb_device *udev = interface_to_usbdev(intf);
const struct usb_device_id *id;
+ struct usb_device_id id_copy;
int error = -ENODEV;
int lpm_disable_error = -ENODEV;
@@ -340,7 +343,7 @@ static int usb_probe_interface(struct device *dev)
return error;
}
- id = usb_match_dynamic_id(intf, driver);
+ id = usb_match_dynamic_id(intf, driver, &id_copy);
if (!id)
id = usb_match_id(intf, driver->id_table);
if (!id)
@@ -892,6 +895,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv)
struct usb_interface *intf;
const struct usb_driver *usb_drv;
const struct usb_device_id *id;
+ struct usb_device_id id_copy;
/* device drivers never match interfaces */
if (is_usb_device_driver(drv))
@@ -904,7 +908,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv)
if (id)
return 1;
- id = usb_match_dynamic_id(intf, usb_drv);
+ id = usb_match_dynamic_id(intf, usb_drv, &id_copy);
if (id)
return 1;
}
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index c11d64bf08fbae..0e7715a02df4cc 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -133,14 +133,14 @@ struct spcp8x5_private {
static int spcp8x5_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
- usb_set_serial_data(serial, (void *)id);
+ usb_set_serial_data(serial, (void *)id->driver_info);
return 0;
}
static int spcp8x5_port_probe(struct usb_serial_port *port)
{
- const struct usb_device_id *id = usb_get_serial_data(port->serial);
+ unsigned int quirks = (unsigned int)(unsigned long)usb_get_serial_data(port->serial);
struct spcp8x5_private *priv;
priv = kzalloc_obj(*priv);
@@ -148,7 +148,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
- priv->quirks = id->driver_info;
+ priv->quirks = quirks;
usb_set_serial_port_data(port, priv);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 1da4ad1610bca0..49ab8dbb885f65 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1185,7 +1185,8 @@ extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf);
* interface. It may also use usb_set_interface() to specify the
* appropriate altsetting. If unwilling to manage the interface,
* return -ENODEV, if genuine IO errors occurred, an appropriate
- * negative errno value.
+ * negative errno value. The usb_device_id parameter is only valid during
+ * probe.
* @disconnect: Called when the interface is no longer accessible, usually
* because its device has been (or is being) disconnected or the
* driver module is being unloaded.
|
| 3/2 | 2026/07/07 20:47 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9432 output: 41 thoughts: 1002 Thoughts: **USB Driver ID Handling: A Potential Vulnerability and Mitigation**
Okay, so I've been reviewing this patch and I've got a good handle on what's changing and why. The crux of it is how we handle `usb_device_id` within the USB subsystem, particularly with dynamic IDs. The current implementation of `usb_match_dynamic_id` appears to be returning a *pointer to a local variable* (`id_copy` specifically, passed as a pointer) which is then used in a `usb_probe_interface`.
That immediately sets off alarm bells. That pointer `id` passed to the probe functions in drivers now potentially points to stack memory, meaning the `id` pointer is only valid within the scope of that `probe` function. This presents a critical problem: if a driver attempts to *save* that `id` pointer for later use (either directly, or by indirectly through another structure), we've got a classic use-after-free or invalid memory access scenario. In essence, any driver that stores a pointer to an id matching a dynamic id, is introducing a vulnerability.
So, the patch's purpose is to mitigate this by changing how these IDs are used by the USB drivers. Let's see how the drivers are changed:
* The patch's impact is pretty broad. I see that the patch touches several drivers.
* `as102_usb_drv.c`, `pegasus.c`, `hif_usb.c`, `xusbatm.c`, `usbtmc.c`, and `spcp8x5.c` are all updated to remove any reliance on the ID pointer. I see the changes implemented for each driver are consistent, the drivers now store relevant data within `driver_info`, instead of relying on pointer arithmetic or by directly storing the ID.
* The `usb_match_dynamic_id` function is being modified, ensuring it copies the ID to a temporary variable and *returns a pointer to that copy*. This is then passed to `usb_probe_interface`. This way the `id` pointer is only valid within the `probe` function and drivers cannot save the `id` pointer for later use.
* This is a good, targeted fix. But how realistic is this vulnerability? With USB drivers, can we trigger this? Yes, certainly. I know we can fuzz USB drivers using tools like dummy\_hcd or raw-gadget, and syzkaller has pretty decent USB fuzzing support as well. That means this is reachable.
Now, I'd like to quickly verify the Kconfig settings to make sure I can test these changes. Let's check:
* `drivers/media/usb/as102/as102_usb_drv.c`: `DVB_AS102`
* `drivers/net/usb/pegasus.c`: `USB_PEGASUS`
* `drivers/net/wireless/ath/ath9k/hif_usb.c`: `ATH9K_HTC`
* `drivers/usb/atm/xusbatm.c`: `USB_XUSBATM`
* `drivers/usb/class/usbtmc.c`: `USB_TMC`
* `drivers/usb/serial/spcp8x5.c`: `USB_SERIAL_SPCP8X5`
I need to confirm these configs are set correctly, but overall, this is a solid patch that addresses a memory safety concern and should be merged.
|
| 4/2 | 2026/07/07 20:47 | tool | grepper |
0mArgs:{
"Expression": "config DVB_AS102",
"PathPrefix": "drivers/media/usb/as102/Kconfig"
}Results: {
"Output": "drivers/media/usb/as102/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/media/usb/as102/Kconfig:2:config DVB_AS102\ndrivers/media/usb/as102/Kconfig-3-\ttristate \"Abilis AS102 DVB receiver\"\n"
} |
| 5/2 | 2026/07/07 20:47 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11334 output: 34 thoughts: 11 Thoughts: Okay, here's my take on those thoughts: **Analyzing DVB-AS102: A Quick Mental Audit** Right, let's break down `DVB_AS102`. My initial thought is to immediately parse this as a standard within the Digital Video Broadcasting (DVB) framework, and the "AS102" likely refers to a specific Application Signaling or implementation guideline. I need to quickly recall the context here. Is this audio-specific? Or more encompassing? Are we talking about a modulation scheme, a specific transport stream arrangement, or an adaptation layer protocol? The context is key, and I’m going to need more to go on to narrow down the relevant specifications. |
| 6/2 | 2026/07/07 20:47 | tool | grepper |
0mArgs:{
"Expression": "config USB_PEGASUS",
"PathPrefix": "drivers/net/usb/Kconfig"
}Results: {
"Output": "drivers/net/usb/Kconfig=34=config USB_KAWETH\n--\ndrivers/net/usb/Kconfig-72-\ndrivers/net/usb/Kconfig:73:config USB_PEGASUS\ndrivers/net/usb/Kconfig-74-\ttristate \"USB Pegasus/Pegasus-II based ethernet device support\"\n"
} |
| 7/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11622 output: 40 thoughts: 9 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and rendered in the first person: **Analyzing the `USB_PEGASUS` Designation** Right, `USB_PEGASUS`. Immediately, my mind goes to the likely implications. The "USB" prefix is, of course, a very specific and fundamental starting point. We're dealing with a Universal Serial Bus interface; that narrows the scope considerably. I'm immediately thinking about the protocol layers, data transfer rates, potential power delivery capabilities, and, most importantly, the target hardware. The "PEGASUS" part, however, is the real key. This strongly suggests a project designation, likely internal, and probably alluding to a significant, possibly complex, undertaking. Given that it's tied to USB, I'm forming hypotheses: is this a custom USB device? A novel USB-based application? Is it related to a specific chipset or controller? Is there an association with the mythical Pegasus in terms of power, speed, or some other symbolic quality? Perhaps this is even a name for a vulnerability or exploit, depending on the context. My immediate next step would be to look for related documentation or past projects, or perhaps more context; keywords, other references, previous implementations or reports. What kind of ecosystem is this within? Any known projects or hardware designs sharing this terminology? The context around it is going to determine my next move. I'd be looking for signal traces, schematics, source code, data sheets... anything to understand what they're doing with this USB interface. The "PEGASUS" is the puzzle piece. |
| 8/2 | 2026/07/07 20:48 | tool | grepper |
0mArgs:{
"Expression": "config ATH9K_HTC",
"PathPrefix": "drivers/net/wireless/ath/ath9k/Kconfig"
}Results: {
"Output": "drivers/net/wireless/ath/ath9k/Kconfig=156=config ATH9K_PCI_NO_EEPROM\n--\ndrivers/net/wireless/ath/ath9k/Kconfig-171-\ndrivers/net/wireless/ath/ath9k/Kconfig:172:config ATH9K_HTC\ndrivers/net/wireless/ath/ath9k/Kconfig-173-\ttristate \"Atheros HTC based wireless cards support\"\n--\ndrivers/net/wireless/ath/ath9k/Kconfig-186-\ndrivers/net/wireless/ath/ath9k/Kconfig:187:config ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/Kconfig-188-\tbool \"Atheros ath9k_htc debugging\"\n"
} |
| 9/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12221 output: 34 thoughts: 9 Thoughts: Okay, here's my understanding of the thought process, summarized as you requested: **Navigating the `ATH9K_HTC` Driver** Alright, let's break this down. My mind immediately goes to the `ATH9K_HTC` driver. I recognize this name; it's a specific, rather intricate piece of the puzzle, isn't it? It's the driver for Atheros AR9003/AR928x family of 802.11n wireless network adapters utilizing the Host Transport Controller (HTC) interface, so this means we're dealing with a specific subset of Atheros hardware, and how it interacts with the system. I have to think about its role in bridging the gap between the hardware and the higher-level networking stack. So, where do I start? I need to consider things like the interface. Is it handling the HTC protocol efficiently? Are there known performance bottlenecks or compatibility issues within specific kernel versions or hardware revisions? Does it handle power management correctly? Is the firmware loading process reliable? Are we seeing any of the classic "firmware crash loop" problems often associated with this family? I'm probably thinking about the implications of dealing with this driver, and how it handles firmware loading, power management, and error handling. I need to keep in mind possible security vulnerabilities associated with the driver. Essentially, I need to evaluate its stability, its efficiency, and any known quirks or limitations within a particular system configuration. It's a key element, this driver. Understanding its nuances is crucial for diagnosing or optimizing wireless performance on any system using this particular chipset. |
| 10/2 | 2026/07/07 20:48 | tool | grepper |
0mArgs:{
"Expression": "config USB_XUSBATM",
"PathPrefix": "drivers/usb/atm/Kconfig"
}Results: {
"Output": "drivers/usb/atm/Kconfig=44=config USB_UEAGLEATM\n--\ndrivers/usb/atm/Kconfig-55-\ndrivers/usb/atm/Kconfig:56:config USB_XUSBATM\ndrivers/usb/atm/Kconfig-57-\ttristate \"Other USB DSL modem support\"\n"
} |
| 11/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12694 output: 33 thoughts: 9 Thoughts: Okay, here's my take on those thoughts, framed as my own: **Analyzing `USB_XUSBATM`** Alright, `USB_XUSBATM`. That name immediately jumps out at me. My mind immediately starts to parse this, thinking, "Okay, this is clearly something related to USB, definitely. The 'XUSB' portion suggests it might be an extended USB protocol, or perhaps something specifically designed for a particular application or hardware. The 'ATM' at the end… hmm, that could mean Asynchronous Transfer Mode, although it's been a while since I've encountered that directly in USB contexts. More likely it's an acronym referring to a particular hardware function set, specific memory allocation or transaction, perhaps. Or, it could be a complete red herring." I start to run through potential implications in my head: "Is this a new USB controller? A driver module? A firmware component? Is it dealing with high-speed data transfer, maybe even pushing the limits of current USB standards? Is it proprietary? Are there relevant patents or specifications I should be aware of? I need to look for documentation, existing codebases, anything that can help me understand the context here. I can't jump to any definite conclusions until I can dive into the details. I will need to look up these components for further context and details." |
| 12/2 | 2026/07/07 20:48 | tool | grepper |
0mArgs:{
"Expression": "config USB_TMC",
"PathPrefix": "drivers/usb/class/Kconfig"
}Results: {
"Output": "drivers/usb/class/Kconfig=31=config USB_WDM\n--\ndrivers/usb/class/Kconfig-40-\ndrivers/usb/class/Kconfig:41:config USB_TMC\ndrivers/usb/class/Kconfig-42-\ttristate \"USB Test and Measurement Class support\"\n"
} |
| 13/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13104 output: 38 thoughts: 8 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience like yourself: **Analyzing the USB_TMC Interface** Alright, so the focus is on `USB_TMC`. Immediately, my mind jumps to the specifics: the *USB Test and Measurement Class* protocol. I'm thinking about the low-level communication aspects. Is this a specific implementation I'm looking at? Are we discussing a particular device using this standard? I'm already anticipating the nuances – the control messages, the bulk transfer mechanisms, and especially the often-problematic interplay between data integrity and latency. Then I'm considering the potential applications. What kind of instrument are we talking about? Oscilloscope? DMM? Spectrum Analyzer? Each instrument type brings its own set of challenges regarding data streams, command syntax, and error handling. I'm mentally parsing the possibilities, considering the expected data formats. Are we dealing with binary data, or ASCII commands? Does the device conform strictly to the standard, or are there manufacturer-specific extensions in play? That's always something I'm on the lookout for. I'm also considering the potential debugging issues. USB can be a bit of a black box sometimes, so how are we going to trace communication, analyze packets, and isolate potential problems? I need to think about suitable tools for sniffing the USB traffic – perhaps using something like Wireshark or a dedicated USB analyzer. And if it's a software implementation I'm dealing with, what are the logging capabilities? Are there any known compatibility issues between specific drivers or operating systems and this specific USB_TMC implementation? I'm already mentally forming a checklist of potential troubleshooting steps. My initial impression is that the task is to understand, implement, troubleshoot, or perhaps optimize a system that relies on this specific protocol. |
| 14/2 | 2026/07/07 20:48 | tool | grepper |
0mArgs:{
"Expression": "config USB_SERIAL_SPCP8X5",
"PathPrefix": "drivers/usb/serial/Kconfig"
}Results: {
"Output": "drivers/usb/serial/Kconfig=475=config USB_SERIAL_QUALCOMM\n--\ndrivers/usb/serial/Kconfig-484-\ndrivers/usb/serial/Kconfig:485:config USB_SERIAL_SPCP8X5\ndrivers/usb/serial/Kconfig-486-\ttristate \"USB SPCP8x5 USB To Serial Driver\"\n"
} |
| 15/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13632 output: 34 thoughts: 152 Thoughts: Okay, here's my breakdown of this. **USB Driver Probing Considerations** Right, so we're talking about `USB_SERIAL_SPCP8X5` in this context. My immediate focus, as always, is on how the system *identifies* and *attaches* a driver to a USB device, specifically this one. My thought process naturally goes to the probing functions. I need to figure out which ones are key to understanding the registration and matching process. The list is: `as102_usb_probe`, `pegasus_probe`, `ath9k_hif_usb_probe`, `xusbatm_bind`, `usbtmc_probe`, `spcp8x5_probe`, `spcp8x5_port_probe`, `usb_probe_interface`, and `usb_device_match`. Quite a few here, but I can see a natural distinction: the ones prefixed with the driver names like `spcp8x5_probe` are probably driver-specific. Then there are those that are generic, core USB functions like `usb_probe_interface` and `usb_device_match`. The probe functions are where the driver actually gets a shot at binding itself. So my analysis needs to involve how these functions are used. My immediate next step is to quickly double-check where the core USB infrastructure resides. I'm going to quickly verify that `usb_probe_interface` and `usb_device_match` are indeed defined in `drivers/usb/core/driver.c`. I need that confirmation before I can proceed with my deep dive; they're the building blocks for how the whole process works. This helps me understand the entry points for the USB subsystem. |
| 16/2 | 2026/07/07 20:48 | tool | grepper |
0mArgs:{
"Expression": "usb_probe_interface",
"PathPrefix": "drivers/usb/core/driver.c"
}Results: {
"Output": "drivers/usb/core/driver.c=305=static int usb_unbind_device(struct device *dev)\n--\ndrivers/usb/core/driver.c-319-/* called from driver core with dev locked */\ndrivers/usb/core/driver.c:320:static int usb_probe_interface(struct device *dev)\ndrivers/usb/core/driver.c-321-{\n--\ndrivers/usb/core/driver.c=1064=int usb_register_driver(struct usb_driver *new_driver, struct module *owner,\n--\ndrivers/usb/core/driver.c-1073-\tnew_driver-\u003edriver.bus = \u0026usb_bus_type;\ndrivers/usb/core/driver.c:1074:\tnew_driver-\u003edriver.probe = usb_probe_interface;\ndrivers/usb/core/driver.c-1075-\tnew_driver-\u003edriver.remove = usb_unbind_interface;\n"
} |
| 17/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14431 output: 34 thoughts: 2 Thoughts: Okay, here's the summary, assuming "Yes" is the complete text and I'm an expert in whatever field it implicitly touches upon: **Affirmation and Immediate Understanding** Right, that's it. *Yes*. The simplicity of it is almost elegant. It's a concise encapsulation of... well, whatever context this is referring to, I already understand it. There's no need for further explanation or elaboration. The implied agreement or confirmation resonates perfectly with my established knowledge and expertise. This single word serves as a conclusive evaluation. It's an unambiguous affirmation. |
| 18/2 | 2026/07/07 20:48 | tool | grepper |
0mArgs:{
"Expression": "usb_device_match",
"PathPrefix": "drivers/usb/core/driver.c"
}Results: {
"Output": "drivers/usb/core/driver.c=838=EXPORT_SYMBOL_GPL(usb_match_id);\ndrivers/usb/core/driver.c-839-\ndrivers/usb/core/driver.c:840:const struct usb_device_id *usb_device_match_id(struct usb_device *udev,\ndrivers/usb/core/driver.c-841-\t\t\t\tconst struct usb_device_id *id)\n--\ndrivers/usb/core/driver.c-852-}\ndrivers/usb/core/driver.c:853:EXPORT_SYMBOL_GPL(usb_device_match_id);\ndrivers/usb/core/driver.c-854-\ndrivers/usb/core/driver.c=855=bool usb_driver_applicable(struct usb_device *udev,\n--\ndrivers/usb/core/driver.c-858-\tif (udrv-\u003eid_table \u0026\u0026 udrv-\u003ematch)\ndrivers/usb/core/driver.c:859:\t\treturn usb_device_match_id(udev, udrv-\u003eid_table) != NULL \u0026\u0026\ndrivers/usb/core/driver.c-860-\t\t udrv-\u003ematch(udev);\n--\ndrivers/usb/core/driver.c-862-\tif (udrv-\u003eid_table)\ndrivers/usb/core/driver.c:863:\t\treturn usb_device_match_id(udev, udrv-\u003eid_table) != NULL;\ndrivers/usb/core/driver.c-864-\n--\ndrivers/usb/core/driver.c-870-\ndrivers/usb/core/driver.c:871:static int usb_device_match(struct device *dev, const struct device_driver *drv)\ndrivers/usb/core/driver.c-872-{\n--\ndrivers/usb/core/driver.c=2080=const struct bus_type usb_bus_type = {\ndrivers/usb/core/driver.c-2081-\t.name =\t\t\"usb\",\ndrivers/usb/core/driver.c:2082:\t.match =\tusb_device_match,\ndrivers/usb/core/driver.c-2083-\t.uevent =\tusb_uevent,\n"
} |
| 19/2 | 2026/07/07 20:48 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15147 output: 300 thoughts: 423 Thoughts: **Analyzing the USB Dynamic ID Patch** Okay, so I'm looking at this patch for the USB core, and my initial thought is: yes, this looks like a critical fix. It's addressing a classic vulnerability – the use-after-free – by changing the way dynamic IDs are handled within the USB subsystem. It's focused on drivers that are naively storing the `usb_device_id` pointer provided during their probe functions. The core of the change revolves around `usb_match_dynamic_id`. Instead of handing out the original pointer, this patch now returns a *copy* of the ID. This is a sound approach; preventing drivers from directly referencing potentially stale data is a solid defense against these memory corruption bugs. The patch also highlights the necessary modifications to several USB drivers to extract the relevant data from `id->driver_info` during the probe, rather than relying on that stored pointer. Given the scope and the nature of the change (touching a core matching function), rigorous testing is absolutely mandatory. I'll need to focus on fuzzing the USB core and the drivers that are affected. The inclusion of `dummy_hcd` and `raw-gadget` is key for constructing a proper fuzzer. It's essential to confirm the new logic works correctly, and importantly, that it doesn't introduce any new regressions. The "WorthFuzzing" flag being true confirms my intuition. I'll concentrate my fuzzing efforts on these key symbols: `usb_probe_interface`, `usb_device_match`, and then dive into the driver-specific probe functions mentioned: `as102_usb_probe`, `pegasus_probe`, `ath9k_hif_usb_probe`, `xusbatm_bind`, `usbtmc_probe`, and `spcp8x5_probe`/`spcp8x5_port_probe`. I'll be sure to enable the respective configurations `DVB_AS102`, `USB_PEGASUS`, `ATH9K_HTC`, `USB_XUSBATM`, `USB_TMC`, and `USB_SERIAL_SPCP8X5` during my testing. This patch warrants a meticulous and thorough fuzzing campaign to ensure its effectiveness and stability. |
| 20/2 | 2026/07/07 20:48 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"DVB_AS102",
"USB_PEGASUS",
"ATH9K_HTC",
"USB_XUSBATM",
"USB_TMC",
"USB_SERIAL_SPCP8X5"
],
"FocusSymbols": [
"usb_probe_interface",
"usb_device_match",
"as102_usb_probe",
"pegasus_probe",
"ath9k_hif_usb_probe",
"xusbatm_bind",
"usbtmc_probe",
"spcp8x5_probe",
"spcp8x5_port_probe"
],
"Reasoning": "The patch changes how dynamic IDs are matched in the USB core to prevent use-after-free bugs when drivers save the `usb_device_id` pointer passed to their `probe` functions. It modifies `usb_match_dynamic_id` to return a copy of the ID, and updates several USB drivers to extract the necessary information from `id-\u003edriver_info` during probe instead of storing the pointer. Fuzzing the USB core and the affected drivers (via dummy_hcd or raw-gadget) is necessary to ensure that the new dynamic ID matching logic and the driver probe functions work correctly and don't introduce regressions.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"DVB_AS102",
"USB_PEGASUS",
"ATH9K_HTC",
"USB_XUSBATM",
"USB_TMC",
"USB_SERIAL_SPCP8X5"
],
"FocusSymbols": [
"usb_probe_interface",
"usb_device_match",
"as102_usb_probe",
"pegasus_probe",
"ath9k_hif_usb_probe",
"xusbatm_bind",
"usbtmc_probe",
"spcp8x5_probe",
"spcp8x5_port_probe"
],
"Reasoning": "The patch changes how dynamic IDs are matched in the USB core to prevent use-after-free bugs when drivers save the `usb_device_id` pointer passed to their `probe` functions. It modifies `usb_match_dynamic_id` to return a copy of the ID, and updates several USB drivers to extract the necessary information from `id-\u003edriver_info` during probe instead of storing the pointer. Fuzzing the USB core and the affected drivers (via dummy_hcd or raw-gadget) is necessary to ensure that the new dynamic ID matching logic and the driver probe functions work correctly and don't introduce regressions.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|