Author: markj
Date: Mon Oct  7 23:35:23 2019
New Revision: 353295
URL: https://svnweb.freebsd.org/changeset/base/353295

Log:
  Improve locking in the IPV6_V6ONLY socket option handler.
  
  Acquire the inp lock before checking whether the socket is already bound,
  and around updates to the inp_vflag field.
  
  MFC after:    1 week
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D21867

Modified:
  head/sys/netinet6/ip6_output.c

Modified: head/sys/netinet6/ip6_output.c
==============================================================================
--- head/sys/netinet6/ip6_output.c      Mon Oct  7 23:31:17 2019        
(r353294)
+++ head/sys/netinet6/ip6_output.c      Mon Oct  7 23:35:23 2019        
(r353295)
@@ -1806,21 +1806,24 @@ do {                                                    
                \
 #endif
 
                                case IPV6_V6ONLY:
-                                       /*
-                                        * make setsockopt(IPV6_V6ONLY)
-                                        * available only prior to bind(2).
-                                        * see ipng mailing list, Jun 22 2001.
-                                        */
+                                       INP_WLOCK(inp);
                                        if (inp->inp_lport ||
                                            
!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
+                                               /*
+                                                * The socket is already bound.
+                                                */
+                                               INP_WUNLOCK(inp);
                                                error = EINVAL;
                                                break;
                                        }
-                                       OPTSET(IN6P_IPV6_V6ONLY);
-                                       if (optval)
+                                       if (optval) {
+                                               inp->inp_flags |= 
IN6P_IPV6_V6ONLY;
                                                inp->inp_vflag &= ~INP_IPV4;
-                                       else
+                                       } else {
+                                               inp->inp_flags &= 
~IN6P_IPV6_V6ONLY;
                                                inp->inp_vflag |= INP_IPV4;
+                                       }
+                                       INP_WUNLOCK(inp);
                                        break;
                                case IPV6_RECVTCLASS:
                                        /* cannot mix with RFC2292 XXX */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to