Skip to content
  • WANG Cong's avatar
    ipv6: check skb->protocol before lookup for nexthop · 199ab00f
    WANG Cong authored
    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: ea3dc960
    
     ("ip6_tunnel: Add support for wildcard tunnel endpoints.")
    Reported-by: default avatarAndrey Konovalov <andreyknvl@google.com>
    Tested-by: default avatarAndrey Konovalov <andreyknvl@google.com>
    Cc: Steffen Klassert <steffen.klassert@secunet.com>
    Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    199ab00f