media: as102: do not rely on id table address comparison

The driver info should be retrieved using the driver_info field, not by
address comparison.

Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-4-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Gary Guo 2026-07-07 13:26:43 +01:00 committed by Greg Kroah-Hartman
parent 934e1322f1
commit 91a8c8c718

View File

@ -24,37 +24,35 @@ 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);
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;
};
#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), \
}
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) },
{ 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 */
};
/* 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 */
};
/* 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 */
};
struct usb_driver as102_usb_driver = {
.name = DRIVER_FULL_NAME,
.probe = as102_usb_probe,
@ -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;