summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/udp6_usrreq.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2009-06-23 22:08:55 +0000
committerbz <bz@FreeBSD.org>2009-06-23 22:08:55 +0000
commita8839212d25048d806814db571facbc74524f2ff (patch)
tree3a58d4c5cc129f8a6f67da930359091b3204e2b3 /sys/netinet6/udp6_usrreq.c
parent6438d166b7094064ec21ed778af3438294b17ed2 (diff)
downloadFreeBSD-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.c9
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) {
OpenPOWER on IntegriCloud