From 4007fe7eae5574db18b61b2a75b9c0fdbc26b1f9 Mon Sep 17 00:00:00 2001 From: delphij Date: Wed, 30 Apr 2014 04:02:57 +0000 Subject: Fix TCP reassembly vulnerability. Patch done by: glebius Security: FreeBSD-SA-14:08.tcp Security: CVE-2014-3000 --- sys/netinet/tcp_reass.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 43153c8..a8ec39c 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -194,7 +194,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -217,7 +217,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -265,7 +265,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data -- cgit v1.1