svn commit: r324179 - head/sys/netinet

Julien Charbon jch at FreeBSD.org
Sun Oct 1 21:20:30 UTC 2017


Author: jch
Date: Sun Oct  1 21:20:28 2017
New Revision: 324179
URL: https://svnweb.freebsd.org/changeset/base/324179

Log:
  Fix an infinite loop in tcp_tw_2msl_scan() when an INP_TIMEWAIT inp has
  been destroyed before its tcptw with INVARIANTS undefined.
  
  This is a symmetric change of r307551:
  
  A INP_TIMEWAIT inp should not be destroyed before its tcptw, and INVARIANTS
  will catch this case.  If INVARIANTS is undefined it will emit a log(LOG_ERR)
  and avoid a hard to debug infinite loop in tcp_tw_2msl_scan().
  
  Reported by:		Ben Rubson, hselasky
  Submitted by:		hselasky
  Tested by:		Ben Rubson, jch
  MFC after:		1 week
  Sponsored by:		Verisign, inc
  Differential Revision:	https://reviews.freebsd.org/D12267

Modified:
  head/sys/netinet/tcp_timewait.c

Modified: head/sys/netinet/tcp_timewait.c
==============================================================================
--- head/sys/netinet/tcp_timewait.c	Sun Oct  1 20:12:30 2017	(r324178)
+++ head/sys/netinet/tcp_timewait.c	Sun Oct  1 21:20:28 2017	(r324179)
@@ -709,10 +709,29 @@ tcp_tw_2msl_scan(int reuse)
 			INP_WLOCK(inp);
 			tw = intotw(inp);
 			if (in_pcbrele_wlocked(inp)) {
-				KASSERT(tw == NULL, ("%s: held last inp "
-				    "reference but tw not NULL", __func__));
-				INP_INFO_RUNLOCK(&V_tcbinfo);
-				continue;
+				if (__predict_true(tw == NULL)) {
+					INP_INFO_RUNLOCK(&V_tcbinfo);
+					continue;
+				} else {
+					/* This should not happen as in TIMEWAIT
+					 * state the inp should not be destroyed
+					 * before its tcptw. If INVARIANTS is
+					 * defined panic.
+					 */
+#ifdef INVARIANTS
+					panic("%s: Panic before an infinite "
+					    "loop: INP_TIMEWAIT && (INP_FREED "
+					    "|| inp last reference) && tw != "
+					    "NULL", __func__);
+#else
+					log(LOG_ERR, "%s: Avoid an infinite "
+					    "loop: INP_TIMEWAIT && (INP_FREED "
+					    "|| inp last reference) && tw != "
+					    "NULL", __func__);
+#endif
+					INP_INFO_RUNLOCK(&V_tcbinfo);
+					break;
+				}
 			}
 
 			if (tw == NULL) {


More information about the svn-src-all mailing list