Author: tuexen
Date: Sat Jul 13 12:45:08 2019
New Revision: 349968
URL: https://svnweb.freebsd.org/changeset/base/349968

Log:
  r348494 fixes a race in udp_output(). The same race exists in
  udp_output6(), therefore apply a similar patch to IPv6.
  
  Reported by:          syzbot+c5ffbc8f14294c7b0...@syzkaller.appspotmail.com
  Reviewed by:          bz@, markj@
  MFC after:            2 weeks
  Sponsored by:         Netflix, Inc.
  Differential Revision:        https://reviews.freebsd.org/D20936

Modified:
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c     Sat Jul 13 10:46:01 2019        
(r349967)
+++ head/sys/netinet6/udp6_usrreq.c     Sat Jul 13 12:45:08 2019        
(r349968)
@@ -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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to