]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
can: ems_usb: ems_usb_read_bulk_callback(): check the proper length of a message
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 23 Feb 2026 16:51:17 +0000 (17:51 +0100)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Mon, 2 Mar 2026 10:03:42 +0000 (11:03 +0100)
When looking at the data in a USB urb, the actual_length is the size of
the buffer passed to the driver, not the transfer_buffer_length which is
set by the driver as the max size of the buffer.

When parsing the messages in ems_usb_read_bulk_callback() properly check
the size both at the beginning of parsing the message to make sure it is
big enough for the expected structure, and at the end of the message to
make sure we don't overflow past the end of the buffer for the next
message.

Cc: Vincent Mailhol <mailhol@kernel.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: stable@kernel.org
Assisted-by: gkh_clanker_2000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/2026022316-answering-strainer-a5db@gregkh
Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/usb/ems_usb.c

index 4c219a5b139bba18827369faf991992c104d6367..9b25dda7c18382105d160feedd679b7f74489ce9 100644 (file)
@@ -445,6 +445,11 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
                start = CPC_HEADER_SIZE;
 
                while (msg_count) {
+                       if (start + CPC_MSG_HEADER_LEN > urb->actual_length) {
+                               netdev_err(netdev, "format error\n");
+                               break;
+                       }
+
                        msg = (struct ems_cpc_msg *)&ibuf[start];
 
                        switch (msg->type) {
@@ -474,7 +479,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
                        start += CPC_MSG_HEADER_LEN + msg->length;
                        msg_count--;
 
-                       if (start > urb->transfer_buffer_length) {
+                       if (start > urb->actual_length) {
                                netdev_err(netdev, "format error\n");
                                break;
                        }