diff options
author | bz <bz@FreeBSD.org> | 2009-06-23 22:08:55 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2009-06-23 22:08:55 +0000 |
commit | a8839212d25048d806814db571facbc74524f2ff (patch) | |
tree | 3a58d4c5cc129f8a6f67da930359091b3204e2b3 /sys/netinet6/udp6_usrreq.c | |
parent | 6438d166b7094064ec21ed778af3438294b17ed2 (diff) | |
download | FreeBSD-src-a8839212d25048d806814db571facbc74524f2ff.zip FreeBSD-src-a8839212d25048d806814db571facbc74524f2ff.tar.gz |
Make callers to in6_selectsrc() and in6_pcbladdr() pass in memory
to save the selected source address rather than returning an
unreferenced copy to a pointer that might long be gone by the
time we use the pointer for anything meaningful.
Asked for by: rwatson
Reviewed by: rwatson
Diffstat (limited to 'sys/netinet6/udp6_usrreq.c')
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 590e6d6..5eb4a47 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -552,7 +552,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, u_int32_t plen = sizeof(struct udphdr) + ulen; struct ip6_hdr *ip6; struct udphdr *udp6; - struct in6_addr *laddr, *faddr; + struct in6_addr *laddr, *faddr, in6a; struct sockaddr_in6 *sin6 = NULL; struct ifnet *oifp = NULL; int scope_ambiguous = 0; @@ -650,13 +650,16 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, } if (!IN6_IS_ADDR_V4MAPPED(faddr)) { - laddr = in6_selectsrc(sin6, optp, inp, NULL, - td->td_ucred, &oifp, &error); + error = in6_selectsrc(sin6, optp, inp, NULL, + td->td_ucred, &oifp, &in6a); + if (error) + goto release; if (oifp && scope_ambiguous && (error = in6_setscope(&sin6->sin6_addr, oifp, NULL))) { goto release; } + laddr = &in6a; } else laddr = &inp->in6p_laddr; /* XXX */ if (laddr == NULL) { |