Commit 747a7135 authored by Gao Feng's avatar Gao Feng Committed by David S. Miller

ipvlan: Fix insufficient skb linear check for ipv6 icmp

In the function ipvlan_get_L3_hdr, current codes use pskb_may_pull to
make sure the skb header has enough linear room for ipv6 header. But it
would use the latter memory directly without linear check when it is icmp.
So it still may access the unepxected memory in ipvlan_addr_lookup.

Now invoke the pskb_may_pull again if it is ipv6 icmp.
Signed-off-by: default avatarGao Feng <gfree.wind@vip.163.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5fc9220a
...@@ -165,8 +165,26 @@ static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int ...@@ -165,8 +165,26 @@ static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int
/* Only Neighbour Solicitation pkts need different treatment */ /* Only Neighbour Solicitation pkts need different treatment */
if (ipv6_addr_any(&ip6h->saddr) && if (ipv6_addr_any(&ip6h->saddr) &&
ip6h->nexthdr == NEXTHDR_ICMP) { ip6h->nexthdr == NEXTHDR_ICMP) {
struct icmp6hdr *icmph;
if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h) + sizeof(*icmph))))
return NULL;
ip6h = ipv6_hdr(skb);
icmph = (struct icmp6hdr *)(ip6h + 1);
if (icmph->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
/* Need to access the ipv6 address in body */
if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h) + sizeof(*icmph)
+ sizeof(struct in6_addr))))
return NULL;
ip6h = ipv6_hdr(skb);
icmph = (struct icmp6hdr *)(ip6h + 1);
}
*type = IPVL_ICMPV6; *type = IPVL_ICMPV6;
lyr3h = ip6h + 1; lyr3h = icmph;
} }
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment