Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Oct 2019 10:44:09 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r353035 - in stable/12/sys/netinet: . tcp_stacks
Message-ID:  <201910031044.x93Ai98N010524@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Thu Oct  3 10:44:09 2019
New Revision: 353035
URL: https://svnweb.freebsd.org/changeset/base/353035

Log:
  MFC r352868:
  
  RFC 7112 requires a host to put the complete IP header chain
  including the TCP header in the first IP packet.
  Enforce this in tcp_output(). In addition make sure that at least
  one byte payload fits in the TCP segement to allow making progress.
  Without this check, a kernel with INVARIANTS will panic.
  This issue was found by running an instance of syzkaller.
  
  Manually resolved a conflict, since we don't have BBR in stable/12.
  
  Reviewed by:		jtl@
  Sponsored by:		Netflix, Inc.
  Differential Revision:	https://reviews.freebsd.org/D21665

Modified:
  stable/12/sys/netinet/tcp_output.c
  stable/12/sys/netinet/tcp_stacks/rack.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/tcp_output.c
==============================================================================
--- stable/12/sys/netinet/tcp_output.c	Thu Oct  3 10:37:53 2019	(r353034)
+++ stable/12/sys/netinet/tcp_output.c	Thu Oct  3 10:44:09 2019	(r353035)
@@ -931,6 +931,20 @@ send:
 			if (tp->t_flags & TF_NEEDFIN)
 				sendalot = 1;
 		} else {
+			if (optlen + ipoptlen >= tp->t_maxseg) {
+				/*
+				 * Since we don't have enough space to put
+				 * the IP header chain and the TCP header in
+				 * one packet as required by RFC 7112, don't
+				 * send it. Also ensure that at least one
+				 * byte of the payload can be put into the
+				 * TCP segment.
+				 */
+				SOCKBUF_UNLOCK(&so->so_snd);
+				error = EMSGSIZE;
+				sack_rxmit = 0;
+				goto out;
+			}
 			len = tp->t_maxseg - optlen - ipoptlen;
 			sendalot = 1;
 			if (dont_sendalot)

Modified: stable/12/sys/netinet/tcp_stacks/rack.c
==============================================================================
--- stable/12/sys/netinet/tcp_stacks/rack.c	Thu Oct  3 10:37:53 2019	(r353034)
+++ stable/12/sys/netinet/tcp_stacks/rack.c	Thu Oct  3 10:44:09 2019	(r353035)
@@ -7954,12 +7954,14 @@ send:
 				sendalot = 1;
 
 		} else {
-			if (optlen + ipoptlen > tp->t_maxseg) {
+			if (optlen + ipoptlen >= tp->t_maxseg) {
 				/*
 				 * Since we don't have enough space to put
 				 * the IP header chain and the TCP header in
 				 * one packet as required by RFC 7112, don't
-				 * send it.
+				 * send it. Also ensure that at least one
+				 * byte of the payload can be put into the
+				 * TCP segment.
 				 */
 				SOCKBUF_UNLOCK(&so->so_snd);
 				error = EMSGSIZE;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910031044.x93Ai98N010524>