svn commit: r324948 - stable/11/sys/netinet

Julien Charbon jch at FreeBSD.org
Tue Oct 24 08:56:12 UTC 2017


Author: jch
Date: Tue Oct 24 08:56:11 2017
New Revision: 324948
URL: https://svnweb.freebsd.org/changeset/base/324948

Log:
  MFC r324179, r324193:
  
  r324179:
  
  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
  Sponsored by:           Verisign, inc
  Differential Revision:  https://reviews.freebsd.org/D12267
  
  r324193:
  
  Forgotten bits in r324179:  Include sys/syslog.h if INVARIANTS is not defined

Modified:
  stable/11/sys/netinet/tcp_timewait.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/tcp_timewait.c
==============================================================================
--- stable/11/sys/netinet/tcp_timewait.c	Tue Oct 24 08:39:05 2017	(r324947)
+++ stable/11/sys/netinet/tcp_timewait.c	Tue Oct 24 08:56:11 2017	(r324948)
@@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#ifndef INVARIANTS
+#include <sys/syslog.h>
+#endif
 #include <sys/protosw.h>
 #include <sys/random.h>
 
@@ -711,10 +714,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