From 183c1076eca43bbb3e7bdf597456f91d81c73e74 Mon Sep 17 00:00:00 2001 From: Adrian Korwel Date: Mon, 25 May 2026 09:58:31 -0500 Subject: USB: serial: io_ti: fix heap overflow in get_manuf_info() get_manuf_info() reads le16_to_cpu(rom_desc->Size) bytes from the device I2C EEPROM into a buffer allocated with kmalloc_obj(), which is sizeof(struct edge_ti_manuf_descriptor) = 10 bytes. The Size field comes from the device and is only validated (in check_i2c_image()) to make sure the descriptor fits within TI_MAX_I2C_SIZE (16384 bytes), not against the destination buffer size. A malicious USB device can therefore set Size to any value up to 16377, causing a heap overflow of up to 16367 bytes when plugged into a host running this driver. valid_csum() is called after read_rom() and also iterates buffer[0..Size-1], compounding the out-of-bounds access. Fix by rejecting descriptors with unexpected length before calling read_rom(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Adrian Korwel [ johan: amend commit message; also check for short descriptors ] Signed-off-by: Johan Hovold --- drivers/usb/serial/io_ti.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index cb55370e036f..6e0d4c38911b 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -773,6 +773,12 @@ static int get_manuf_info(struct edgeport_serial *serial, u8 *buffer) } /* Read the descriptor data */ + if (le16_to_cpu(rom_desc->Size) != sizeof(struct edge_ti_manuf_descriptor)) { + dev_err(dev, "unexpected Edge descriptor length: %u\n", + le16_to_cpu(rom_desc->Size)); + status = -EINVAL; + goto exit; + } status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc), le16_to_cpu(rom_desc->Size), buffer); if (status) -- cgit v1.2.3 From 0fd2b00b2d3d05e3eaa13342b3dfb0fa85c226ae Mon Sep 17 00:00:00 2001 From: Adrian Korwel Date: Mon, 25 May 2026 09:58:32 -0500 Subject: USB: serial: io_ti: fix heap overflow in build_i2c_fw_hdr() build_i2c_fw_hdr() allocates a fixed-size buffer of (16*1024 - 512) + sizeof(struct ti_i2c_firmware_rec) bytes, then copies le16_to_cpu(img_header->Length) bytes into it without validating that Length fits within the available space after the firmware record header. img_header->Length is a __le16 from the firmware file and can be up to 65535. check_fw_sanity() validates the total firmware size but not img_header->Length specifically. Fix by rejecting images where img_header->Length exceeds the available destination space. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Adrian Korwel Signed-off-by: Johan Hovold --- drivers/usb/serial/io_ti.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 6e0d4c38911b..d48819d785ef 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -844,6 +844,11 @@ static int build_i2c_fw_hdr(u8 *header, const struct firmware *fw) /* Pointer to fw_down memory image */ img_header = (struct ti_i2c_image_header *)&fw->data[4]; + if (le16_to_cpu(img_header->Length) > + buffer_size - sizeof(struct ti_i2c_firmware_rec)) { + kfree(buffer); + return -EINVAL; + } memcpy(buffer + sizeof(struct ti_i2c_firmware_rec), &fw->data[4 + sizeof(struct ti_i2c_image_header)], le16_to_cpu(img_header->Length)); -- cgit v1.2.3 From 1938fb9fe38c4f04a3f30bea44f8071c80a63be4 Mon Sep 17 00:00:00 2001 From: Jack Wu Date: Thu, 4 Jun 2026 10:04:40 +0800 Subject: USB: serial: option: add usb-id for Dell Wireless DW5826e-m Add support for Dell DW5826e-m with USB-id 0x413c:0x81ea T: Bus=03 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=413c ProdID=81ea Rev= 5.04 S: Manufacturer=DELL S: Product=DW5826e-m Qualcomm Snapdragon X12 Global LTE-A S: SerialNumber=358988870177734 C:* #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#=12 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I:* If#=12 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#=13 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#=13 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Jack Wu Reviewed-by: Lars Melin Cc: stable@vger.kernel.org [ johan: reserve also interface 4 ] Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 48ae0188f2e9..a34e79cfd5b6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -202,6 +202,7 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5821E_ESIM 0x81e0 #define DELL_PRODUCT_5829E_ESIM 0x81e4 #define DELL_PRODUCT_5829E 0x81e6 +#define DELL_PRODUCT_5826E_ESIM 0x81ea #define DELL_PRODUCT_FM101R_ESIM 0x8213 #define DELL_PRODUCT_FM101R 0x8215 @@ -1123,6 +1124,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(0) | RSVD(6) }, { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), .driver_info = RSVD(0) | RSVD(6) }, + { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_5826E_ESIM, 0xff), + .driver_info = RSVD(1) | RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R_ESIM, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ -- cgit v1.2.3