svn commit: r351971 - stable/12/sys/netinet6
Michael Tuexen
tuexen at FreeBSD.org
Sat Sep 7 10:45:45 UTC 2019
Author: tuexen
Date: Sat Sep 7 10:45:44 2019
New Revision: 351971
URL: https://svnweb.freebsd.org/changeset/base/351971
Log:
MFC r349968:
r348494 fixes a race in udp_output(). The same race exists in
udp_output6(), therefore apply a similar patch to IPv6.
Reviewed by: bz@, markj@
Differential Revision: https://reviews.freebsd.org/D20936
Modified:
stable/12/sys/netinet6/udp6_usrreq.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/netinet6/udp6_usrreq.c
==============================================================================
--- stable/12/sys/netinet6/udp6_usrreq.c Sat Sep 7 10:39:49 2019 (r351970)
+++ stable/12/sys/netinet6/udp6_usrreq.c Sat Sep 7 10:45:44 2019 (r351971)
@@ -742,9 +742,24 @@ udp6_output(struct socket *so, int flags_arg, struct m
* - when we are not bound to an address and source port (it is
* in6_pcbsetport() which will require the write lock).
*/
+retry:
if (sin6 == NULL || (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
inp->inp_lport == 0)) {
INP_WLOCK(inp);
+ /*
+ * In case we lost a race and another thread bound addr/port
+ * on the inp we cannot keep the wlock (which still would be
+ * fine) as further down, based on these values we make
+ * decisions for the pcbinfo lock. If the locks are not in
+ * synch the assertions on unlock will fire, hence we go for
+ * one retry loop.
+ */
+ if (sin6 != NULL &&
+ (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) ||
+ inp->inp_lport != 0)) {
+ INP_WUNLOCK(inp);
+ goto retry;
+ }
unlock_inp = UH_WLOCKED;
} else {
INP_RLOCK(inp);
More information about the svn-src-stable
mailing list