summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/udp6_usrreq.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-09-22 06:44:03 +0000
committerrwatson <rwatson@FreeBSD.org>2008-09-22 06:44:03 +0000
commit12ddb86062ec9a98a39ff603770a010dc8852f59 (patch)
tree53e9ec42f885e05246545b8f8a2ec0aa6bfd08a1 /sys/netinet6/udp6_usrreq.c
parent514fd19ec3b25f4b0ae5633eb65c3edc1731f626 (diff)
downloadFreeBSD-src-12ddb86062ec9a98a39ff603770a010dc8852f59.zip
FreeBSD-src-12ddb86062ec9a98a39ff603770a010dc8852f59.tar.gz
When invoking the udp_send() from udp6_send() due to use of a v6-mapped
IPv4 address, first drop the udbinfo and inpcb locks, which will otherwise be recursed. This leads to a potential minor race, but is preferable to a deadlock when acquiring a read lock after a write lock on the inpcb. MFC after: 3 days Reported by: Norbert Papke <fbsd-ml@scrapper.ca>, lioux
Diffstat (limited to 'sys/netinet6/udp6_usrreq.c')
-rw-r--r--sys/netinet6/udp6_usrreq.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index fa943d5..7d50c1b 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -976,13 +976,23 @@ udp6_send(struct socket *so, int flags, struct mbuf *m,
error = EINVAL;
goto out;
}
+
+ /*
+ * XXXRW: We release UDP-layer locks before calling
+ * udp_send() in order to avoid recursion. However,
+ * this does mean there is a short window where inp's
+ * fields are unstable. Could this lead to a
+ * potential race in which the factors causing us to
+ * select the UDPv4 output routine are invalidated?
+ */
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_udbinfo);
if (sin6)
in6_sin6_2_sin_in_sock(addr);
pru = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs;
- error = ((*pru->pru_send)(so, flags, m, addr, control,
- td));
/* addr will just be freed in sendit(). */
- goto out;
+ return ((*pru->pru_send)(so, flags, m, addr, control,
+ td));
}
}
#endif
OpenPOWER on IntegriCloud