summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/icmp6.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-06-23 20:19:09 +0000
committerrwatson <rwatson@FreeBSD.org>2009-06-23 20:19:09 +0000
commitc9ef486fe1d7da6a2212a337eacc5ed5b40f85d9 (patch)
tree5ce1a7dad67026f119a839b3325454ebafa72c51 /sys/netinet6/icmp6.c
parentf75c2385c686d82292982283b5f0a9c9988beda8 (diff)
downloadFreeBSD-src-c9ef486fe1d7da6a2212a337eacc5ed5b40f85d9.zip
FreeBSD-src-c9ef486fe1d7da6a2212a337eacc5ed5b40f85d9.tar.gz
Modify most routines returning 'struct ifaddr *' to return references
rather than pointers, requiring callers to properly dispose of those references. The following routines now return references: ifaddr_byindex ifa_ifwithaddr ifa_ifwithbroadaddr ifa_ifwithdstaddr ifa_ifwithnet ifaof_ifpforaddr ifa_ifwithroute ifa_ifwithroute_fib rt_getifa rt_getifa_fib IFP_TO_IA ip_rtaddr in6_ifawithifp in6ifa_ifpforlinklocal in6ifa_ifpwithaddr in6_ifadd carp_iamatch6 ip6_getdstifaddr Remove unused macro which didn't have required referencing: IFP_TO_IA6 This closes many small races in which changes to interface or address lists while an ifaddr was in use could lead to use of freed memory (etc). In a few cases, add missing if_addr_list locking required to safely acquire references. Because of a lack of deep copying support, we accept a race in which an in6_ifaddr pointed to by mbuf tags and extracted with ip6_getdstifaddr() doesn't hold a reference while in transmit. Once we have mbuf tag deep copy support, this can be fixed. Reviewed by: bz Obtained from: Apple, Inc. (portions) MFC after: 6 weeks (portions)
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r--sys/netinet6/icmp6.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 11e6cd6..786ddc2 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1244,11 +1244,13 @@ ni6_input(struct mbuf *m, int off)
if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) &&
!(V_icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) {
+ ifa_free(&ia6->ia_ifa);
nd6log((LOG_DEBUG, "ni6_input: ignore node info to "
"a temporary address in %s:%d",
__FILE__, __LINE__));
goto bad;
}
+ ifa_free(&ia6->ia_ifa);
}
/* validate query Subject field. */
@@ -2074,7 +2076,7 @@ icmp6_reflect(struct mbuf *m, size_t off)
INIT_VNET_INET6(curvnet);
struct ip6_hdr *ip6;
struct icmp6_hdr *icmp6;
- struct in6_ifaddr *ia;
+ struct in6_ifaddr *ia = NULL;
int plen;
int type, code;
struct ifnet *outif = NULL;
@@ -2220,9 +2222,13 @@ icmp6_reflect(struct mbuf *m, size_t off)
if (outif)
icmp6_ifoutstat_inc(outif, type, code);
+ if (ia != NULL)
+ ifa_free(&ia->ia_ifa);
return;
bad:
+ if (ia != NULL)
+ ifa_free(&ia->ia_ifa);
m_freem(m);
return;
}
@@ -2541,6 +2547,8 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
IN6_IFF_ANYCAST)) == NULL)
goto fail;
ifp_ll6 = &ia->ia_addr.sin6_addr;
+ /* XXXRW: reference released prematurely. */
+ ifa_free(&ia->ia_ifa);
}
/* get ip6 linklocal address for the router. */
OpenPOWER on IntegriCloud