From: Adrian Korwel <adriank20047@gmail.com> stable inclusion from stable-v6.6.143 commit d92f17af7097d10bdeddf26f66f34b354104b277 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/15882 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- commit 183c1076eca43bbb3e7bdf597456f91d81c73e74 upstream. 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 <adriank20047@gmail.com> [ johan: amend commit message; also check for short descriptors ] Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Hulk Robot <hulkci@huawei.com> Signed-off-by: Mingrui Liu <liumingrui@huawei.com> --- 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 c41fbc321b35..45184faf02bc 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) -- 2.34.1