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 --- 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