svn commit: r271089 - head/sys/netinet

Gleb Smirnoff glebius at FreeBSD.org
Thu Sep 4 09:15:44 UTC 2014


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:
 	/*


More information about the svn-src-head mailing list