[PATCH] net: usb: asix: fix off-by-one in rx_fixup bounds check
From: Aamir Ahmed <hidden>
Date: 2026-09-07 07:52:11
The sync check in asix_rx_fixup_internal() validates:
rx->remaining + sizeof(u32) <= skb->len
then reads at:
offset = ((rx->remaining + 1) & 0xfffe);
rx->header = get_unaligned_le32(skb->data + offset);
When rx->remaining is odd, the alignment rounding makes offset larger
than rx->remaining. For example with rx->remaining=3 and skb->len=7:
check passes (3+4<=7) but offset becomes ((3+1)&0xfffe)=4, and the
4-byte read at offset 4 needs 8 bytes total, causing a 1-byte
heap OOB read.
Fix the bounds check to use the actual aligned offset that will be
used for the read.
Fixes: 3f30b158eba5 ("asix: On RX avoid creating bad Ethernet frames")
Cc: stable@vger.kernel.org
Assisted-by: Claude (Anthropic)
Signed-off-by: Aamir Ahmed <redacted>
---
drivers/net/usb/asix_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
index 4f03f4e57655d..c50646ea35c7e 100644
--- a/drivers/net/usb/asix_common.c
+++ b/drivers/net/usb/asix_common.c@@ -148,7 +148,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb, * Also avoid unnecessarily discarding a good current netdev socket * buffer. */ - if (rx->remaining && (rx->remaining + sizeof(u32) <= skb->len)) { + if (rx->remaining && (((rx->remaining + 1) & 0xfffe) + sizeof(u32) <= skb->len)) { offset = ((rx->remaining + 1) & 0xfffe); rx->header = get_unaligned_le32(skb->data + offset); offset = 0;
--
2.43.0