Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Sep 2014 09:15:44 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271089 - head/sys/netinet
Message-ID:  <201409040915.s849FiTT005615@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Thu Sep  4 09:15:44 2014
New Revision: 271089
URL: http://svnweb.freebsd.org/changeset/base/271089

Log:
  Improve r265338. When inserting mbufs into TCP reassembly queue,
  try to collapse adjacent pieces using m_catpkt(). In best case
  scenario it copies data and frees mbufs, making mbuf exhaustion
  attack harder.
  
  Suggested by:		Jonathan Looney <jonlooney gmail.com>
  Security:		Hardens against remote mbuf exhaustion attack.
  Sponsored by:		Netflix
  Sponsored by:		Nginx, Inc.

Modified:
  head/sys/netinet/tcp_reass.c

Modified: head/sys/netinet/tcp_reass.c
==============================================================================
--- head/sys/netinet/tcp_reass.c	Thu Sep  4 09:07:14 2014	(r271088)
+++ head/sys/netinet/tcp_reass.c	Thu Sep  4 09:15:44 2014	(r271089)
@@ -214,16 +214,29 @@ tcp_reass(struct tcpcb *tp, struct tcphd
 		mq = nq;
 	}
 
-	/* Insert the new segment queue entry into place. */
+	/*
+	 * Insert the new segment queue entry into place.  Try to collapse
+	 * mbuf chains if segments are adjacent.
+	 */
 	if (mp) {
-		m->m_nextpkt = mp->m_nextpkt;
-		mp->m_nextpkt = m;
+		if (M_TCPHDR(mp)->th_seq + mp->m_pkthdr.len == th->th_seq)
+			m_catpkt(mp, m);
+		else {
+			m->m_nextpkt = mp->m_nextpkt;
+			mp->m_nextpkt = m;
+			m->m_pkthdr.pkt_tcphdr = th;
+		}
 	} else {
-		m->m_nextpkt = tp->t_segq;
-		tp->t_segq = m ;
+		mq = tp->t_segq;
+		tp->t_segq = m;
+		if (mq && th->th_seq + *tlenp == M_TCPHDR(mq)->th_seq) {
+			m->m_nextpkt = mq->m_nextpkt;
+			m_catpkt(m, mq);
+		} else
+			m->m_nextpkt = mq;
+		m->m_pkthdr.pkt_tcphdr = th;
 	}
-	m->m_pkthdr.pkt_tcphdr = th;
-	tp->t_segqlen += m->m_pkthdr.len;
+	tp->t_segqlen += *tlenp;
 
 present:
 	/*



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