* [PATCH net v2] net: usb: catc: bound the RX packet length in catc_rx_done()
@ 2026-09-14 23:06 Aamir Ahmed
2026-09-17 9:08 ` Simon Horman
2026-09-17 13:00 ` Paolo Abeni
0 siblings, 2 replies; 3+ messages in thread
From: Aamir Ahmed @ 2026-09-14 23:06 UTC (permalink / raw)
To: Andrew Lunn
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Peter Korsgaard, Ziyi Guo, Ethan Nelson-Moore, linux-usb, netdev,
linux-kernel, Aamir Ahmed
catc_rx_done() walks a multi-packet URB, reading a two-byte length from
each packet header. Its bound, pkt_len > urb->actual_length, ignores the
header offset and compares against the whole transfer rather than the
bytes left from pkt_start, so a crafted packet header makes
skb_copy_to_linear_data() read past the buffer.
A length below ETH_HLEN is also accepted, including zero, and
eth_type_trans() then reads a MAC header from the uninitialised tailroom
of a shorter skb. The is_f5u011 branch takes its length straight from
the transfer, so a zero-length URB reaches the same path.
Track the bytes remaining from the current packet, and reject a header
that does not fit, a length past what is left, and a length below an
Ethernet header.
A transfer shorter than an Ethernet header, including a zero-length one,
previously became a runt skb passed to netif_rx() and counted as
received; it is now counted in rx_length_errors and ends the walk.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by: LLM
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
---
v2:
- reject pkt_len below ETH_HLEN, covering the is_f5u011 branch too (Sashiko)
- hoist the remaining-bytes calculation so one check bounds both ends
- drop Cc: stable; no conforming device reaches this
- add Assisted-by: LLM
v1: https://lore.kernel.org/netdev/AS8P251MB00013A0DCA600A79DC58B0FEC8B22@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM/
Sashiko also suggested a sanity maximum on pkt_len. I left it out: PKT_SZ
would reject the 1537-1600 byte transfers the is_f5u011 path allows, since
RX_PKT_SZ is 1600, and dev->mtu excludes the MAC header that pkt_len
includes.
Built with W=1 (catc.o) on x86_64; no warnings. I have no CATC hardware,
so this is not runtime-tested.
drivers/net/usb/catc.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 96e82f94edcf..39b678f175dd 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -233,17 +233,26 @@ static void catc_rx_done(struct urb *urb)
}
do {
- if(!catc->is_f5u011) {
- pkt_len = le16_to_cpup((__le16*)pkt_start);
- if (pkt_len > urb->actual_length) {
+ int remaining = urb->actual_length -
+ (pkt_start - (u8 *)urb->transfer_buffer);
+
+ if (!catc->is_f5u011) {
+ if (remaining < pkt_offset) {
catc->netdev->stats.rx_length_errors++;
catc->netdev->stats.rx_errors++;
break;
}
+ pkt_len = le16_to_cpup((__le16 *)pkt_start);
} else {
pkt_len = urb->actual_length;
}
+ if (pkt_len < ETH_HLEN || pkt_len + pkt_offset > remaining) {
+ catc->netdev->stats.rx_length_errors++;
+ catc->netdev->stats.rx_errors++;
+ break;
+ }
+
if (!(skb = dev_alloc_skb(pkt_len)))
return;
base-commit: c297ed90fbba72d32b7759aae362b36d15b2db1f
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH net v2] net: usb: catc: bound the RX packet length in catc_rx_done()
2026-09-14 23:06 [PATCH net v2] net: usb: catc: bound the RX packet length in catc_rx_done() Aamir Ahmed
@ 2026-09-17 9:08 ` Simon Horman
2026-09-17 13:00 ` Paolo Abeni
1 sibling, 0 replies; 3+ messages in thread
From: Simon Horman @ 2026-09-17 9:08 UTC (permalink / raw)
To: Aamir Ahmed
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Peter Korsgaard, Ziyi Guo, Ethan Nelson-Moore,
linux-usb, netdev, linux-kernel
On Tue, Sep 15, 2026 at 12:06:58AM +0100, Aamir Ahmed wrote:
> catc_rx_done() walks a multi-packet URB, reading a two-byte length from
> each packet header. Its bound, pkt_len > urb->actual_length, ignores the
> header offset and compares against the whole transfer rather than the
> bytes left from pkt_start, so a crafted packet header makes
> skb_copy_to_linear_data() read past the buffer.
>
> A length below ETH_HLEN is also accepted, including zero, and
> eth_type_trans() then reads a MAC header from the uninitialised tailroom
> of a shorter skb. The is_f5u011 branch takes its length straight from
> the transfer, so a zero-length URB reaches the same path.
>
> Track the bytes remaining from the current packet, and reject a header
> that does not fit, a length past what is left, and a length below an
> Ethernet header.
>
> A transfer shorter than an Ethernet header, including a zero-length one,
> previously became a runt skb passed to netif_rx() and counted as
> received; it is now counted in rx_length_errors and ends the walk.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Assisted-by: LLM
> Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
> ---
> v2:
> - reject pkt_len below ETH_HLEN, covering the is_f5u011 branch too (Sashiko)
> - hoist the remaining-bytes calculation so one check bounds both ends
> - drop Cc: stable; no conforming device reaches this
> - add Assisted-by: LLM
> v1: https://lore.kernel.org/netdev/AS8P251MB00013A0DCA600A79DC58B0FEC8B22@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM/
>
> Sashiko also suggested a sanity maximum on pkt_len. I left it out: PKT_SZ
> would reject the 1537-1600 byte transfers the is_f5u011 path allows, since
> RX_PKT_SZ is 1600, and dev->mtu excludes the MAC header that pkt_len
> includes.
>
> Built with W=1 (catc.o) on x86_64; no warnings. I have no CATC hardware,
> so this is not runtime-tested.
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH net v2] net: usb: catc: bound the RX packet length in catc_rx_done()
2026-09-14 23:06 [PATCH net v2] net: usb: catc: bound the RX packet length in catc_rx_done() Aamir Ahmed
2026-09-17 9:08 ` Simon Horman
@ 2026-09-17 13:00 ` Paolo Abeni
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Abeni @ 2026-09-17 13:00 UTC (permalink / raw)
To: Aamir Ahmed, Andrew Lunn
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Peter Korsgaard,
Ziyi Guo, Ethan Nelson-Moore, linux-usb, netdev, linux-kernel
On 9/15/26 01:06, Aamir Ahmed wrote:
> catc_rx_done() walks a multi-packet URB, reading a two-byte length from
> each packet header. Its bound, pkt_len > urb->actual_length, ignores the
> header offset and compares against the whole transfer rather than the
> bytes left from pkt_start, so a crafted packet header makes
> skb_copy_to_linear_data() read past the buffer.
>
> A length below ETH_HLEN is also accepted, including zero, and
> eth_type_trans() then reads a MAC header from the uninitialised tailroom
> of a shorter skb. The is_f5u011 branch takes its length straight from
> the transfer, so a zero-length URB reaches the same path.
>
> Track the bytes remaining from the current packet, and reject a header
> that does not fit, a length past what is left, and a length below an
> Ethernet header.
>
> A transfer shorter than an Ethernet header, including a zero-length one,
> previously became a runt skb passed to netif_rx() and counted as
> received; it is now counted in rx_length_errors and ends the walk.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Assisted-by: LLM
> Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
I'm sorry, but no minor fixes for legacy drivers.
/P
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-17 13:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-14 23:06 [PATCH net v2] net: usb: catc: bound the RX packet length in catc_rx_done() Aamir Ahmed
2026-09-17 9:08 ` Simon Horman
2026-09-17 13:00 ` Paolo Abeni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®