]> git.baikalelectronics.ru Git - kernel.git/commit
ipv6: check skb->protocol before lookup for nexthop
authorWANG Cong <xiyou.wangcong@gmail.com>
Tue, 25 Apr 2017 21:37:15 +0000 (14:37 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 26 Apr 2017 18:51:26 +0000 (14:51 -0400)
commit7fc43b692b81811eb6d84972656bad302ca2f4e5
tree39b0f2f29102ade5b355f6ef1e68441f5072514c
parent924ced02c3ff0818be69b7487333c455c70b0964
ipv6: check skb->protocol before lookup for nexthop

Andrey reported a out-of-bound access in ip6_tnl_xmit(), this
is because we use an ipv4 dst in ip6_tnl_xmit() and cast an IPv4
neigh key as an IPv6 address:

        neigh = dst_neigh_lookup(skb_dst(skb),
                                 &ipv6_hdr(skb)->daddr);
        if (!neigh)
                goto tx_err_link_failure;

        addr6 = (struct in6_addr *)&neigh->primary_key; // <=== HERE
        addr_type = ipv6_addr_type(addr6);

        if (addr_type == IPV6_ADDR_ANY)
                addr6 = &ipv6_hdr(skb)->daddr;

        memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));

Also the network header of the skb at this point should be still IPv4
for 4in6 tunnels, we shold not just use it as IPv6 header.

This patch fixes it by checking if skb->protocol is ETH_P_IPV6: if it
is, we are safe to do the nexthop lookup using skb_dst() and
ipv6_hdr(skb)->daddr; if not (aka IPv4), we have no clue about which
dest address we can pick here, we have to rely on callers to fill it
from tunnel config, so just fall to ip6_route_output() to make the
decision.

Fixes: 3c8caeac6587 ("ip6_tunnel: Add support for wildcard tunnel endpoints.")
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Tested-by: Andrey Konovalov <andreyknvl@google.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/ip6_tunnel.c