Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

ipv6: Fix OOPS in ip6_dst_lookup_tail().

This fixes kernel bugzilla 11469: "TUN with 1024 neighbours:
ip6_dst_lookup_tail NULL crash"

dst->neighbour is not necessarily hooked up at this point
in the processing path, so blindly dereferencing it is
the wrong thing to do. This NULL check exists in other
similar paths and this case was just an oversight.

Also fix the completely wrong and confusing indentation
here while we're at it.

Based upon a patch by Evgeniy Polyakov.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Neil Horman and committed by
David S. Miller
e550dfb0 225f4005

+29 -29
+29 -29
net/ipv6/ip6_output.c
··· 943 943 } 944 944 945 945 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD 946 - /* 947 - * Here if the dst entry we've looked up 948 - * has a neighbour entry that is in the INCOMPLETE 949 - * state and the src address from the flow is 950 - * marked as OPTIMISTIC, we release the found 951 - * dst entry and replace it instead with the 952 - * dst entry of the nexthop router 953 - */ 954 - if (!((*dst)->neighbour->nud_state & NUD_VALID)) { 955 - struct inet6_ifaddr *ifp; 956 - struct flowi fl_gw; 957 - int redirect; 946 + /* 947 + * Here if the dst entry we've looked up 948 + * has a neighbour entry that is in the INCOMPLETE 949 + * state and the src address from the flow is 950 + * marked as OPTIMISTIC, we release the found 951 + * dst entry and replace it instead with the 952 + * dst entry of the nexthop router 953 + */ 954 + if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { 955 + struct inet6_ifaddr *ifp; 956 + struct flowi fl_gw; 957 + int redirect; 958 958 959 - ifp = ipv6_get_ifaddr(net, &fl->fl6_src, 960 - (*dst)->dev, 1); 959 + ifp = ipv6_get_ifaddr(net, &fl->fl6_src, 960 + (*dst)->dev, 1); 961 961 962 - redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); 963 - if (ifp) 964 - in6_ifa_put(ifp); 962 + redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); 963 + if (ifp) 964 + in6_ifa_put(ifp); 965 965 966 - if (redirect) { 967 - /* 968 - * We need to get the dst entry for the 969 - * default router instead 970 - */ 971 - dst_release(*dst); 972 - memcpy(&fl_gw, fl, sizeof(struct flowi)); 973 - memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); 974 - *dst = ip6_route_output(net, sk, &fl_gw); 975 - if ((err = (*dst)->error)) 976 - goto out_err_release; 977 - } 966 + if (redirect) { 967 + /* 968 + * We need to get the dst entry for the 969 + * default router instead 970 + */ 971 + dst_release(*dst); 972 + memcpy(&fl_gw, fl, sizeof(struct flowi)); 973 + memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); 974 + *dst = ip6_route_output(net, sk, &fl_gw); 975 + if ((err = (*dst)->error)) 976 + goto out_err_release; 978 977 } 978 + } 979 979 #endif 980 980 981 981 return 0;