|
|
@@ -153,7 +153,7 @@ static bool qmimux_has_slaves(struct usbnet *dev)
|
|
|
|
|
|
static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
|
|
{
|
|
|
- unsigned int len, offset = 0;
|
|
|
+ unsigned int len, offset = 0, pad_len, pkt_len;
|
|
|
struct qmimux_hdr *hdr;
|
|
|
struct net_device *net;
|
|
|
struct sk_buff *skbn;
|
|
|
@@ -171,10 +171,16 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
|
|
if (hdr->pad & 0x80)
|
|
|
goto skip;
|
|
|
|
|
|
+ /* extract padding length and check for valid length info */
|
|
|
+ pad_len = hdr->pad & 0x3f;
|
|
|
+ if (len == 0 || pad_len >= len)
|
|
|
+ goto skip;
|
|
|
+ pkt_len = len - pad_len;
|
|
|
+
|
|
|
net = qmimux_find_dev(dev, hdr->mux_id);
|
|
|
if (!net)
|
|
|
goto skip;
|
|
|
- skbn = netdev_alloc_skb(net, len);
|
|
|
+ skbn = netdev_alloc_skb(net, pkt_len);
|
|
|
if (!skbn)
|
|
|
return 0;
|
|
|
skbn->dev = net;
|
|
|
@@ -191,7 +197,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
|
|
goto skip;
|
|
|
}
|
|
|
|
|
|
- skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len);
|
|
|
+ skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, pkt_len);
|
|
|
if (netif_rx(skbn) != NET_RX_SUCCESS)
|
|
|
return 0;
|
|
|
|