[PATCH] net: usb: catc: fix out-of-bounds read in catc_rx_done()

DORMANTno replies

From: Aamir Ahmed <hidden>
Date: 2026-09-07 07:25:40
Also in: netdev, stable
Subsystem: networking drivers, the rest, usb networking drivers · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

catc_rx_done() parses multi-packet USB transfers by iterating over the
received data. For each packet, it reads a 2-byte little-endian length
from the buffer, then copies that many bytes as the packet payload.

The bounds check "pkt_len > urb->actual_length" is insufficient:

1. It does not account for the 2-byte header offset, so the memcpy can
   read 2 bytes beyond the received data.

2. For subsequent packets in the same URB, pkt_start advances through
   the buffer but the check still compares against the total
   urb->actual_length rather than the remaining bytes, allowing reads
   well past the end.

Fix this by calculating the remaining bytes from the current pkt_start
position and checking both that enough bytes exist to read the header
and that the packet length plus header fits within the remaining data.

A malicious USB device can craft transfers that trigger the out-of-bounds
heap read.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Aamir Ahmed <redacted>
Assisted-by: Claude (Anthropic)
---
 drivers/net/usb/catc.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 96e82f94edcf8..e4f8b9a0caf19 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -234,8 +234,16 @@ static void catc_rx_done(struct urb *urb)
 
 	do {
 		if(!catc->is_f5u011) {
+			int remaining = urb->actual_length -
+					(pkt_start - (u8 *)urb->transfer_buffer);
+
+			if (remaining < pkt_offset) {
+				catc->netdev->stats.rx_length_errors++;
+				catc->netdev->stats.rx_errors++;
+				break;
+			}
 			pkt_len = le16_to_cpup((__le16*)pkt_start);
-			if (pkt_len > urb->actual_length) {
+			if (pkt_len + pkt_offset > remaining) {
 				catc->netdev->stats.rx_length_errors++;
 				catc->netdev->stats.rx_errors++;
 				break;
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help