Message ID | CAPgLHd-Z5azR2_5O+GkdjBF45k8YY1te0huMo75pFULGHG+izg@mail.gmail.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Wei Yongjun <weiyj.lk@gmail.com> Date: Thu, 2 Feb 2012 14:17:23 +0800 > From: Wei Yongjun <yongjun_wei@trendmicro.com.cn> > > The packets with size larger than 1452 will be dropped by bridge > which with two hyperv netdevice ports. This cause by hyperv netvsc > driver always copy the trailer padding to the data packet, and then > the skb received from netdevice may include wrong skb->len (20 bytes > larger than the real size normally). The captured packet may like > this: > > Ethernet II, Src: Microsof_00:00:07 (00:15:5d:00:00:07), > Dst: HewlettP_00:00:4e (00:1f:29:00:00:4e) > Destination: HewlettP_e6:00:4e (00:1f:29:00:00:4e) > Source: Microsof_f6:6d:07 (00:15:5d:f6:6d:07) > Type: IP (0x0800) > Trailer: 1415161718191A1B1C1D1E1F20212223 > Frame check sequence: 0x24252627 [incorrect, should be 0x7c2e5a5e] > > The following command help to reproduction it, and the ping ICMP > packets will be dropped by bridge. > $ ping ip -s 1453 > > This patch fixed it by removing the trailer padding from the data > packet. > > Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn> Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index da181f9..dc2e384 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -321,6 +321,25 @@ static void rndis_filter_receive_data(struct rndis_device *dev, data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; pkt->total_data_buflen -= data_offset; + + /* + * Make sure we got a valid RNDIS message, now total_data_buflen + * should be the data packet size plus the trailer padding size + */ + if (pkt->total_data_buflen < rndis_pkt->data_len) { + netdev_err(dev->net_dev->ndev, "rndis message buffer " + "overflow detected (got %u, min %u)" + "...dropping this message!\n", + pkt->total_data_buflen, rndis_pkt->data_len); + return; + } + + /* + * Remove the rndis trailer padding from rndis packet message + * rndis_pkt->data_len tell us the real data length, we only copy + * the data packet to the stack, without the rndis trailer padding + */ + pkt->total_data_buflen = rndis_pkt->data_len; pkt->data = (void *)((unsigned long)pkt->data + data_offset); pkt->is_data_pkt = true;