Author: sbruno
Date: Wed Jul  4 17:10:07 2018
New Revision: 335962
URL: https://svnweb.freebsd.org/changeset/base/335962

Log:
  fix locking within tcp_ipsec_pcbctl() to match ipsec4_pcbctl(), 
ipsec4_pcbctl()
  
  IPSEC_PCBCTL() functions, which include tcp_ipsec_pcbctl(),
  ipsec4_pcbctl(), and ipsec6_pcbctl(), should all have matching locking
  semantics.
  
  ipsec4_pcbctl() and ipsec6_pcbctl() expect the inp to be unlocked on
  entry and exit and appear to be correctly implemented as such. But
  tcp_ipsec_pcbctl() had other semantics. This patch fixes the semantics
  for tcp_ipsec_pcbctl().
  
  Submitted by: Jason Eggleston <ja...@eggnet.com>
  MFH:          2 weeks
  Sponsored by: Limelight Networks
  Differential Revision:        https://reviews.freebsd.org/D14623

Modified:
  head/sys/netipsec/xform_tcp.c

Modified: head/sys/netipsec/xform_tcp.c
==============================================================================
--- head/sys/netipsec/xform_tcp.c       Wed Jul  4 17:06:51 2018        
(r335961)
+++ head/sys/netipsec/xform_tcp.c       Wed Jul  4 17:10:07 2018        
(r335962)
@@ -80,23 +80,24 @@ tcp_ipsec_pcbctl(struct inpcb *inp, struct sockopt *so
        struct tcpcb *tp;
        int error, optval;
 
-       INP_WLOCK_ASSERT(inp);
        if (sopt->sopt_name != TCP_MD5SIG) {
-               INP_WUNLOCK(inp);
                return (ENOPROTOOPT);
        }
 
-       tp = intotcpcb(inp);
        if (sopt->sopt_dir == SOPT_GET) {
+               INP_RLOCK(inp);
+               if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+                       INP_RUNLOCK(inp);
+                       return (ECONNRESET);
+               }
+               tp = intotcpcb(inp);
                optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
-               INP_WUNLOCK(inp);
+               INP_RUNLOCK(inp);
 
                /* On success return with released INP_WLOCK */
                return (sooptcopyout(sopt, &optval, sizeof(optval)));
        }
 
-       INP_WUNLOCK(inp);
-
        error = sooptcopyin(sopt, &optval, sizeof(optval), sizeof(optval));
        if (error != 0)
                return (error);
@@ -107,12 +108,13 @@ tcp_ipsec_pcbctl(struct inpcb *inp, struct sockopt *so
                INP_WUNLOCK(inp);
                return (ECONNRESET);
        }
+       tp = intotcpcb(inp);
        if (optval > 0)
                tp->t_flags |= TF_SIGNATURE;
        else
                tp->t_flags &= ~TF_SIGNATURE;
 
-       /* On success return with acquired INP_WLOCK */
+       INP_WUNLOCK(inp);
        return (error);
 }
 
_______________________________________________
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