Author: trociny
Date: Sun Nov  6 09:29:52 2011
New Revision: 227206
URL: http://svn.freebsd.org/changeset/base/227206

Log:
  Before dereferencing intotw() check for NULL, the same way as it is
  done for in_pcb (see r157474).
  
  MFC after:    1 week

Modified:
  head/sys/netinet6/in6_pcb.c

Modified: head/sys/netinet6/in6_pcb.c
==============================================================================
--- head/sys/netinet6/in6_pcb.c Sun Nov  6 09:27:40 2011        (r227205)
+++ head/sys/netinet6/in6_pcb.c Sun Nov  6 09:29:52 2011        (r227206)
@@ -187,6 +187,7 @@ in6_pcbbind(register struct inpcb *inp, 
                }
                if (lport) {
                        struct inpcb *t;
+                       struct tcptw *tw;
 
                        /* GROSS */
                        if (ntohs(lport) <= V_ipport_reservedhigh &&
@@ -233,10 +234,21 @@ in6_pcbbind(register struct inpcb *inp, 
                        }
                        t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
                            lport, lookupflags, cred);
-                       if (t && (reuseport & ((t->inp_flags & INP_TIMEWAIT) ?
-                           intotw(t)->tw_so_options :
-                           t->inp_socket->so_options)) == 0)
+                       if (t && (t->inp_flags & INP_TIMEWAIT)) {
+                               /*
+                                * XXXRW: If an incpb has had its timewait
+                                * state recycled, we treat the address as
+                                * being in use (for now).  This is better
+                                * than a panic, but not desirable.
+                                */
+                               tw = intotw(t);
+                               if (tw == NULL ||
+                                   (reuseport & tw->tw_so_options) == 0)
+                                       return (EADDRINUSE);
+                       } else if (t && (reuseport & t->inp_socket->so_options)
+                           == 0) {
                                return (EADDRINUSE);
+                       }
 #ifdef INET
                        if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
                            IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
@@ -246,9 +258,11 @@ in6_pcbbind(register struct inpcb *inp, 
                                t = in_pcblookup_local(pcbinfo, sin.sin_addr,
                                    lport, lookupflags, cred);
                                if (t && t->inp_flags & INP_TIMEWAIT) {
-                                       if ((reuseport &
-                                           intotw(t)->tw_so_options) == 0 &&
-                                           (ntohl(t->inp_laddr.s_addr) !=
+                                       tw = intotw(t);
+                                       if (tw == NULL)
+                                               return (EADDRINUSE);
+                                       if ((reuseport & tw->tw_so_options) == 0
+                                           && (ntohl(t->inp_laddr.s_addr) !=
                                             INADDR_ANY || ((inp->inp_vflag &
                                             INP_IPV6PROTO) ==
                                             (t->inp_vflag & INP_IPV6PROTO))))
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to