aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2014-04-30 04:05:47 +0000
committerXin LI <delphij@FreeBSD.org>2014-04-30 04:05:47 +0000
commit4ff0eebe6394759f3658bfdb1623149ebbd810ea (patch)
treef8ac49815ab2ee5dd9ffef05f8f93659a893ae5d
parenta6ec1268220db10ca6e5843572ba73d1a24b88fa (diff)
downloadsrc-4ff0eebe6394759f3658bfdb1623149ebbd810ea.tar.gz
src-4ff0eebe6394759f3658bfdb1623149ebbd810ea.zip
Fix TCP reassembly vulnerability.releng/8.3
Security: FreeBSD-SA-14:08.tcp Security: CVE-2014-3000 Approved by: so
Notes
Notes: svn path=/releng/8.3/; revision=265125
-rw-r--r--UPDATING4
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/netinet/tcp_reass.c7
3 files changed, 9 insertions, 4 deletions
diff --git a/UPDATING b/UPDATING
index cf3907dcb7c5..bed3305a808e 100644
--- a/UPDATING
+++ b/UPDATING
@@ -15,6 +15,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
debugging tools present in HEAD were left in place because
sun4v support still needs work to become production ready.
+20140430: p16 FreeBSD-SA-14:08.tcp
+
+ Fix TCP reassembly vulnerability. [SA-14:08]
+
20140408: p15 FreeBSD-SA-14:05.nfsserver
FreeBSD-SA-14:06.openssl
Fix deadlock in the NFS server. [SA-14:05]
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 7eae356e139a..1a44a6a1c86b 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="8.3"
-BRANCH="RELEASE-p15"
+BRANCH="RELEASE-p16"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index f5248106e9b7..4658e0e1f8fc 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -211,7 +211,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);
@@ -234,7 +234,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;
@@ -282,7 +282,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