Skip to contentSkip to conversation

can: kvaser_usb: leaf: Fix infinite loop on zero-length cmd

PATCH In review pip-izony 2 participants 3 messages Oct 23, 2025 CAN network drivers

lore
Share & tools
lore

pip-izony

author
#0 lore raw

PATCH 1/1 can: kvaser_usb: leaf: Fix infinite loop on zero-length cmd

From: Seungjin Bae <[email protected]>

The kvaser_usb_leaf_read_bulk_callback() function parse received command buffers from the device. The firmware may insert zero-length placeholder commands to handle alignment with the USB endpoint's wMaxPacketSize.

The driver attempts to skip these placeholders by aligning the buffer position pos to the next packet boundary using round_up() function.

However, if zero-length command is found exactly on a packet boundary (i.e., pos is a multiple of wMaxPacketSize, including 0), round_up function will return the unchanged value of pos. This prevents pos to be increased, causing an infinite loop in the parsing logic.

I fixed this in the function by using pos + 1 instead. This ensures that even if pos is on a boundary, the calculation is based on pos + 1, forcing round_up() to always return the next aligned boundary.

Fixes 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +1 -1
index c29828a94ad0..4da6d4ba4e1e 100644
@@ -1732,7 +1732,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
 		 * number of events in case of a heavy rx load on the bus.
 		 */
 		if (cmd->len == 0) {
-			pos = round_up(pos, le16_to_cpu
+			pos = round_up(pos + 1, le16_to_cpu
 						(dev->bulk_in->wMaxPacketSize));
 			continue;
 		}
Signature · 1 line
2.43.0
#1 lore raw
Quoted 10 lines · pip-izony

From: Seungjin Bae <[email protected]>

The kvaser_usb_leaf_read_bulk_callback() function parse received command buffers from the device. The firmware may insert zero-length placeholder commands to handle alignment with the USB endpoint's wMaxPacketSize.

The driver attempts to skip these placeholders by aligning the buffer position pos to the next packet boundary using round_up() function.

What about the round_up() in kvaser_usb_leaf_wait_cmd()? Is it also affected by this problem?

Marc

Signature · 4 lines
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
author
#2 lore raw

PATCH v2 1/1 can: kvaser_usb: leaf: Fix potential infinite loop in command parsers

From: Seungjin Bae <[email protected]>

kvaser_usb_leaf_wait_cmd() and kvaser_usb_leaf_read_bulk_callback functions contain logic to handle zero-length commands. These commands are used to align data to the USB endpoint's wMaxPacketSize boundary.

The driver attempts to skip these placeholders by aligning the buffer position pos to the next packet boundary using round_up() function.

However, if zero-length command is found exactly on a packet boundary (i.e., pos is a multiple of wMaxPacketSize, including 0), round_up function will return the unchanged value of pos. This prevents pos to be increased, causing an infinite loop in the parsing logic.

This patch fixes this in the function by using pos + 1 instead. This ensures that even if pos is on a boundary, the calculation is based on pos + 1, forcing round_up() to always return the next aligned boundary.

Fixes 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")

---
v1 -> v2: Apply the same infinite loop fix to kvaser_usb_leaf_wait_cmd()

 drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +2 -2
index c29828a94ad0..1167d38344f1 100644
@@ -685,7 +685,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
 			 * for further details.
 			 */
 			if (tmp->len == 0) {
-				pos = round_up(pos,
+				pos = round_up(pos + 1,
 					       le16_to_cpu
 						(dev->bulk_in->wMaxPacketSize));
 				continue;
@@ -1732,7 +1732,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
 		 * number of events in case of a heavy rx load on the bus.
 		 */
 		if (cmd->len == 0) {
-			pos = round_up(pos, le16_to_cpu
+			pos = round_up(pos + 1, le16_to_cpu
 						(dev->bulk_in->wMaxPacketSize));
 			continue;
 		}
Signature · 1 line
2.43.0