diff options
author | glebius <glebius@FreeBSD.org> | 2014-09-04 09:15:44 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2014-09-04 09:15:44 +0000 |
commit | ae21082d79820db4832b2e5dbee75b5bdba98f66 (patch) | |
tree | b3f17318e9cda7076d33c1b732a63606f09ca387 /sys | |
parent | 9bd9cb7c21e8cf6c5c195b00f1a2b5b2ff20283d (diff) | |
download | FreeBSD-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.c | 27 |
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: /* |