summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2014-09-04 09:15:44 +0000
committerglebius <glebius@FreeBSD.org>2014-09-04 09:15:44 +0000
commitae21082d79820db4832b2e5dbee75b5bdba98f66 (patch)
treeb3f17318e9cda7076d33c1b732a63606f09ca387 /sys
parent9bd9cb7c21e8cf6c5c195b00f1a2b5b2ff20283d (diff)
downloadFreeBSD-src-ae21082d79820db4832b2e5dbee75b5bdba98f66.zip
FreeBSD-src-ae21082d79820db4832b2e5dbee75b5bdba98f66.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_reass.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 14f0e93..d7efe1d 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -214,16 +214,29 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
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:
/*
OpenPOWER on IntegriCloud