svn commit: r298673 - head/sys/netinet

Conrad E. Meyer cem at FreeBSD.org
Tue Apr 26 23:02:20 UTC 2016


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


More information about the svn-src-head mailing list