diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 0f69b77e8..85e48000f 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1234,6 +1234,9 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; struct ethtool_eee eee_data; + /* XXX is this a right place? */ + set_bit(EVENT_NO_IP_ALIGN, &dev->flags); + usbnet_get_endpoints(dev, intf); tmp16 = (u16 *)buf; @@ -1383,6 +1386,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) pkt_cnt = (u16)rx_hdr; hdr_off = (u16)(rx_hdr >> 16); + if (hdr_off + sizeof(u32)*pkt_cnt > skb->len) { + /* XXX misbehaving or malicious device, report? */ + return 0; + } pkt_hdr = (u32 *)(skb->data + hdr_off); while (pkt_cnt--) { @@ -1390,11 +1397,19 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) le32_to_cpus(pkt_hdr); pkt_len = (*pkt_hdr >> 16) & 0x1fff; + if (pkt_len + 2 > skb->len) { + /* XXX misbehaving or malicious device, report? */ + return 0; + } /* Check CRC or runt packet */ if ((*pkt_hdr & AX_RXHDR_CRC_ERR) || (*pkt_hdr & AX_RXHDR_DROP_ERR)) { - skb_pull(skb, (pkt_len + 7) & 0xFFF8); + /* XXX actual packet size is (2+pkt_len), but we advance by pkt_len here? */ + if (skb_pull(skb, (pkt_len + 7) & 0xFFF8) == NULL) { + /* misbehaving or malicious device, report? */ + return 0; + } pkt_hdr++; continue; } @@ -1421,7 +1436,11 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 0; } - skb_pull(skb, (pkt_len + 7) & 0xFFF8); + /* XXX packet size is always (2+pkt_len), but we advance by pkt_len here? */ + if (skb_pull(skb, (pkt_len + 7) & 0xFFF8) == NULL) { + /* misbehaving or malicious device, report? */ + return 0; + } pkt_hdr++; } return 1;