Netdev List
 help / color / mirror / Atom feed
* [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet
@ 2026-06-25 15:32 Tianchu Chen
  2026-06-30  0:44 ` Jakub Kicinski
  0 siblings, 1 reply; 5+ messages in thread
From: Tianchu Chen @ 2026-06-25 15:32 UTC (permalink / raw)
  To: andrew+netdev, davem, edumazet, kuba, pabeni; +Cc: linux-usb, netdev

From: Tianchu Chen <flynnnchen@tencent.com>

Discovered by Atuin - Automated Vulnerability Discovery Engine.

cx82310_rx_fixup() treats an RX length of 0xffff as a device reboot
marker and schedules work to re-enable ethernet mode, but then continues
processing the marker as a normal packet length. This is an out-of-bounds
heap write controlled by the usb device.

Return immediately after scheduling the recovery work so the marker skb
is dropped instead of being assembled as packet data.

Fixes: ca139d76b0d9 ("cx82310_eth: re-enable ethernet mode after router reboot")
Cc: stable@vger.kernel.org
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
---
 drivers/net/usb/cx82310_eth.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c
index 068acb052..5df657acf 100644
--- a/drivers/net/usb/cx82310_eth.c
+++ b/drivers/net/usb/cx82310_eth.c
@@ -282,6 +282,7 @@ static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 		if (len == 0xffff) {
 			netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
 			schedule_work(&priv->reenable_work);
+			return 0;
 		} else if (len > CX82310_MTU) {
 			netdev_err(dev->net, "RX packet too long: %d B\n", len);
 			return 0;
-- 
2.51.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet
  2026-06-25 15:32 [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet Tianchu Chen
@ 2026-06-30  0:44 ` Jakub Kicinski
  2026-06-30 10:30   ` Tianchu Chen
  0 siblings, 1 reply; 5+ messages in thread
From: Jakub Kicinski @ 2026-06-30  0:44 UTC (permalink / raw)
  To: Tianchu Chen; +Cc: andrew+netdev, davem, edumazet, pabeni, linux-usb, netdev

On Thu, 25 Jun 2026 15:32:04 +0000 Tianchu Chen wrote:
> From: Tianchu Chen <flynnnchen@tencent.com>
> 
> Discovered by Atuin - Automated Vulnerability Discovery Engine.
> 
> cx82310_rx_fixup() treats an RX length of 0xffff as a device reboot
> marker and schedules work to re-enable ethernet mode, but then continues
> processing the marker as a normal packet length. This is an out-of-bounds
> heap write controlled by the usb device.

Where? Can you be more specific in the commit message? At a glance 
the accesses seem to be bound-checked with skb->len.
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet
  2026-06-30  0:44 ` Jakub Kicinski
@ 2026-06-30 10:30   ` Tianchu Chen
  2026-06-30 22:42     ` Jakub Kicinski
  0 siblings, 1 reply; 5+ messages in thread
From: Tianchu Chen @ 2026-06-30 10:30 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: andrew+netdev, davem, edumazet, pabeni, linux-usb, netdev

June 30, 2026 at 8:44 AM, "Jakub Kicinski" <kuba@kernel.org mailto:kuba@kernel.org?to=%22Jakub%20Kicinski%22%20%3Ckuba%40kernel.org%3E > wrote:

> 
> On Thu, 25 Jun 2026 15:32:04 +0000 Tianchu Chen wrote:
> 
> > 
> > From: Tianchu Chen <flynnnchen@tencent.com>
> >  
> >  Discovered by Atuin - Automated Vulnerability Discovery Engine.
> >  
> >  cx82310_rx_fixup() treats an RX length of 0xffff as a device reboot
> >  marker and schedules work to re-enable ethernet mode, but then continues
> >  processing the marker as a normal packet length. This is an out-of-bounds
> >  heap write controlled by the usb device.
> > 
> Where? Can you be more specific in the commit message? At a glance 
> the accesses seem to be bound-checked with skb->len.
> -- 
> pw-bot: cr
>


The "len > skb->len" check bounds the source read, but the overflow is on the
destination buffer.

The buggy path is:

	if (len == 0xffff) {
		netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
		schedule_work(&priv->reenable_work);
		/* <- BUG: missing return; 0xffff bypasses the oversized-length reject */
	} else if (len > CX82310_MTU) {
		netdev_err(dev->net, "RX packet too long: %d B\n", len);
		return 0;
	}
	if (len > skb->len) {
		dev->partial_len = skb->len; // skb->len is bounded by the USB transfer size (4K)
		dev->partial_rem = len - skb->len;
		memcpy((void *)dev->partial_data, skb->data,
		       dev->partial_len); /* <- TRIGGER: can copy 4K bytes into 1516-byte partial_data */
...
...
	}

For normal oversized lengths, the len > CX82310_MTU branch rejects
before this copy. But 0xffff is special-cased and falls through. With a
4096-byte RX URB, after the 2-byte length header is pulled, skb->len can
be 4094, while partial_data is allocated as dev->hard_mtu
(CX82310_MTU + 2, 1516 bytes).

So the source read is bounded by skb->len; the destination write is not.

I am happy to send a v2 with this spelled out more clearly in the commit message
if needed.

Best regards,
Tianchu Chen

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet
  2026-06-30 10:30   ` Tianchu Chen
@ 2026-06-30 22:42     ` Jakub Kicinski
  2026-07-01  2:45       ` Tianchu Chen
  0 siblings, 1 reply; 5+ messages in thread
From: Jakub Kicinski @ 2026-06-30 22:42 UTC (permalink / raw)
  To: Tianchu Chen; +Cc: andrew+netdev, davem, edumazet, pabeni, linux-usb, netdev

On Tue, 30 Jun 2026 10:30:53 +0000 Tianchu Chen wrote:
> June 30, 2026 at 8:44 AM, "Jakub Kicinski" <kuba@kernel.org mailto:kuba@kernel.org?to=%22Jakub%20Kicinski%22%20%3Ckuba%40kernel.org%3E > wrote:
> > On Thu, 25 Jun 2026 15:32:04 +0000 Tianchu Chen wrote:
> > > From: Tianchu Chen <flynnnchen@tencent.com>
> > >  
> > >  Discovered by Atuin - Automated Vulnerability Discovery Engine.
> > >  
> > >  cx82310_rx_fixup() treats an RX length of 0xffff as a device reboot
> > >  marker and schedules work to re-enable ethernet mode, but then continues
> > >  processing the marker as a normal packet length. This is an out-of-bounds
> > >  heap write controlled by the usb device.
> > >   
> > Where? Can you be more specific in the commit message? At a glance 
> > the accesses seem to be bound-checked with skb->len.
> > -- 
> > pw-bot: cr
> >  
> 
> 
> The "len > skb->len" check bounds the source read, but the overflow is on the
> destination buffer.
> 
> The buggy path is:
> 
> 	if (len == 0xffff) {
> 		netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
> 		schedule_work(&priv->reenable_work);
> 		/* <- BUG: missing return; 0xffff bypasses the oversized-length reject */
> 	} else if (len > CX82310_MTU) {
> 		netdev_err(dev->net, "RX packet too long: %d B\n", len);
> 		return 0;
> 	}
> 	if (len > skb->len) {
> 		dev->partial_len = skb->len; // skb->len is bounded by the USB transfer size (4K)
> 		dev->partial_rem = len - skb->len;
> 		memcpy((void *)dev->partial_data, skb->data,
> 		       dev->partial_len); /* <- TRIGGER: can copy 4K bytes into 1516-byte partial_data */

If skb->len (== dev->partial_len) is not bound-checked to the size
of dev->partial_data - aren't there more paths that could hit this
overflow? Are you fixing the right thing?

> ...
> ...
> 	}
> 
> For normal oversized lengths, the len > CX82310_MTU branch rejects
> before this copy. But 0xffff is special-cased and falls through. With a
> 4096-byte RX URB, after the 2-byte length header is pulled, skb->len can
> be 4094, while partial_data is allocated as dev->hard_mtu
> (CX82310_MTU + 2, 1516 bytes).
> 
> So the source read is bounded by skb->len; the destination write is not.
> 
> I am happy to send a v2 with this spelled out more clearly in the commit message
> if needed.
> 
> Best regards,
> Tianchu Chen
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet
  2026-06-30 22:42     ` Jakub Kicinski
@ 2026-07-01  2:45       ` Tianchu Chen
  0 siblings, 0 replies; 5+ messages in thread
From: Tianchu Chen @ 2026-07-01  2:45 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: andrew+netdev, davem, edumazet, pabeni, linux-usb, netdev

July 1, 2026 at 6:42 AM, "Jakub Kicinski" <kuba@kernel.org mailto:kuba@kernel.org?to=%22Jakub%20Kicinski%22%20%3Ckuba%40kernel.org%3E > wrote:

> 
> On Tue, 30 Jun 2026 10:30:53 +0000 Tianchu Chen wrote:
> 
> > 
> > June 30, 2026 at 8:44 AM, "Jakub Kicinski" <kuba@kernel.org mailto:kuba@kernel.org?to=%22Jakub%20Kicinski%22%20%3Ckuba%40kernel.org%3E > wrote:
> >  On Thu, 25 Jun 2026 15:32:04 +0000 Tianchu Chen wrote:
> >  > From: Tianchu Chen <flynnnchen@tencent.com>
> >  > 
> >  > Discovered by Atuin - Automated Vulnerability Discovery Engine.
> >  > 
> >  > cx82310_rx_fixup() treats an RX length of 0xffff as a device reboot
> >  > marker and schedules work to re-enable ethernet mode, but then continues
> >  > processing the marker as a normal packet length. This is an out-of-bounds
> >  > heap write controlled by the usb device.
> >  > 
> >  Where? Can you be more specific in the commit message? At a glance 
> >  the accesses seem to be bound-checked with skb->len.
> >  -- 
> >  pw-bot: cr
> >  
> >  
> >  
> >  The "len > skb->len" check bounds the source read, but the overflow is on the
> >  destination buffer.
> >  
> >  The buggy path is:
> >  
> >  if (len == 0xffff) {
> >  netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
> >  schedule_work(&priv->reenable_work);
> >  /* <- BUG: missing return; 0xffff bypasses the oversized-length reject */
> >  } else if (len > CX82310_MTU) {
> >  netdev_err(dev->net, "RX packet too long: %d B\n", len);
> >  return 0;
> >  }
> >  if (len > skb->len) {
> >  dev->partial_len = skb->len; // skb->len is bounded by the USB transfer size (4K)
> >  dev->partial_rem = len - skb->len;
> >  memcpy((void *)dev->partial_data, skb->data,
> >  dev->partial_len); /* <- TRIGGER: can copy 4K bytes into 1516-byte partial_data */
> > 
> If skb->len (== dev->partial_len) is not bound-checked to the size
> of dev->partial_data - aren't there more paths that could hit this
> overflow? Are you fixing the right thing?

Yes, skb->len and CX82310_MTU are different limits here.

skb->len is the amount of data received in the current USB RX URB. This
driver sets dev->rx_urb_size to 4096, so skb->len can be much larger than
the network frame MTU.

The safety invariant for the partial_data copy is not that skb->len is
MTU-bounded by itself. It is that, for normal frames, the code first rejects
len > CX82310_MTU, and then reaches the partial-packet path only when
len > skb->len. Therefore, on the normal path:

	skb->len < len <= CX82310_MTU

so copying skb->len bytes into partial_data is safe, since partial_data is
allocated as dev->hard_mtu = CX82310_MTU + 2.

The 0xffff reboot marker is the only case that breaks that invariant:
len == 0xffff is handled in a separate branch, and it just bypasses the
"len > CX82310_MTU" check entirely.

So the only case that may trigger this OOB-write is len == 0xffff, which is a
reboot signal and should be skipped from being parsed as normal packet.

Also, skb->len is governed by the USB RX URB size, not by the network MTU;
it is a different length limit from CX82310_MTU.

I believe this addresses the concern, but please let me know if you see any
remaining issue and/or would prefer a v2.


Best regards,
Tianchu

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-01  2:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-25 15:32 [PATCH] net: usb: cx82310_eth: stop parsing reboot marker as packet Tianchu Chen
2026-06-30  0:44 ` Jakub Kicinski
2026-06-30 10:30   ` Tianchu Chen
2026-06-30 22:42     ` Jakub Kicinski
2026-07-01  2:45       ` Tianchu Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox