vmxnet3: fix incorrect dereference when rxvlan is disabled
vmxnet3_get_hdr_len() is used to calculate the header length which in turn is used to calculate the gso_size for skb. When rxvlan offload is disabled, vlan tag is present in the header and the function references ip header from sizeof(ethhdr) and leads to incorrect pointer reference. This patch fixes this issue by taking sizeof(vlan_ethhdr) into account if vlan tag is present and correctly references the ip hdr. Signed-off-by: Ronak Doshi <doshir@vmware.com> Acked-by: Guolin Yang <gyang@vmware.com> Acked-by: Louis Luo <llouis@vmware.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
f7e4367268
commit
65ec0bd1c7
@@ -1218,6 +1218,7 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
|
||||
union {
|
||||
void *ptr;
|
||||
struct ethhdr *eth;
|
||||
struct vlan_ethhdr *veth;
|
||||
struct iphdr *ipv4;
|
||||
struct ipv6hdr *ipv6;
|
||||
struct tcphdr *tcp;
|
||||
@@ -1228,16 +1229,24 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
|
||||
if (unlikely(sizeof(struct iphdr) + sizeof(struct tcphdr) > maplen))
|
||||
return 0;
|
||||
|
||||
if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
|
||||
skb->protocol == cpu_to_be16(ETH_P_8021AD))
|
||||
hlen = sizeof(struct vlan_ethhdr);
|
||||
else
|
||||
hlen = sizeof(struct ethhdr);
|
||||
|
||||
hdr.eth = eth_hdr(skb);
|
||||
if (gdesc->rcd.v4) {
|
||||
BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP));
|
||||
hdr.ptr += sizeof(struct ethhdr);
|
||||
BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP) &&
|
||||
hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IP));
|
||||
hdr.ptr += hlen;
|
||||
BUG_ON(hdr.ipv4->protocol != IPPROTO_TCP);
|
||||
hlen = hdr.ipv4->ihl << 2;
|
||||
hdr.ptr += hdr.ipv4->ihl << 2;
|
||||
} else if (gdesc->rcd.v6) {
|
||||
BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6));
|
||||
hdr.ptr += sizeof(struct ethhdr);
|
||||
BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6) &&
|
||||
hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IPV6));
|
||||
hdr.ptr += hlen;
|
||||
/* Use an estimated value, since we also need to handle
|
||||
* TSO case.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user