Author: cem
Date: Tue Apr 26 23:02:18 2016
New Revision: 298673
URL: https://svnweb.freebsd.org/changeset/base/298673

Log:
  tcp_usrreq: Free allocated buffer in relock case
  
  The disgusting macro INP_WLOCK_RECHECK may early-return.  In
  tcp_default_ctloutput() the TCP_CCALGOOPT case allocates memory before 
invoking
  this macro, which may leak memory.
  
  Add a _CLEANUP variant that takes a code argument to perform variable cleanup
  in the early return path.  Use it to free the 'pbuf' allocated in
  tcp_default_ctloutput().
  
  I am not especially happy with this macro, but I reckon it's not any worse 
than
  INP_WLOCK_RECHECK already was.
  
  Reported by:  Coverity
  CID:          1350286
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sys/netinet/tcp_usrreq.c

Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c       Tue Apr 26 22:32:33 2016        
(r298672)
+++ head/sys/netinet/tcp_usrreq.c       Tue Apr 26 23:02:18 2016        
(r298673)
@@ -1361,14 +1361,16 @@ tcp_fill_info(struct tcpcb *tp, struct t
  * has to revalidate that the connection is still valid for the socket
  * option.
  */
-#define INP_WLOCK_RECHECK(inp) do {                                    \
+#define INP_WLOCK_RECHECK_CLEANUP(inp, cleanup) do {                   \
        INP_WLOCK(inp);                                                 \
        if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {            \
                INP_WUNLOCK(inp);                                       \
+               cleanup;                                                \
                return (ECONNRESET);                                    \
        }                                                               \
        tp = intotcpcb(inp);                                            \
 } while(0)
+#define INP_WLOCK_RECHECK(inp) INP_WLOCK_RECHECK_CLEANUP((inp), /* noop */)
 
 int
 tcp_ctloutput(struct socket *so, struct sockopt *sopt)
@@ -1497,7 +1499,7 @@ tcp_default_ctloutput(struct socket *so,
                        free(pbuf, M_TEMP);
                        return (error);
                }
-               INP_WLOCK_RECHECK(inp);
+               INP_WLOCK_RECHECK_CLEANUP(inp, free(pbuf, M_TEMP));
                if (CC_ALGO(tp)->ctl_output != NULL)
                        error = CC_ALGO(tp)->ctl_output(tp->ccv, sopt, pbuf);
                else
@@ -1838,6 +1840,7 @@ unlock_and_done:
        return (error);
 }
 #undef INP_WLOCK_RECHECK
+#undef INP_WLOCK_RECHECK_CLEANUP
 
 /*
  * Attach TCP protocol to socket, allocating
_______________________________________________
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