Skip to content
Browse files

FreeBSD Security Advisory: FreeBSD-SA-04:04.tcp

  • Loading branch information...
1 parent 249592f commit f09af18546d364556c54da2db7ef3036039ec21d suz committed Mar 3, 2004
Showing with 52 additions and 1 deletion.
  1. +6 −1 CHANGELOG
  2. +37 −0 freebsd4/sys/netinet/tcp_input.c
  3. +7 −0 freebsd4/sys/netinet/tcp_subr.c
  4. +2 −0 freebsd4/sys/netinet/tcp_var.h
View
7 CHANGELOG
@@ -1,5 +1,10 @@
CHANGELOG for KAME kit
-$KAME: CHANGELOG,v 1.2551 2004/02/28 10:24:55 jinmei Exp $
+$KAME: CHANGELOG,v 1.2552 2004/03/03 15:04:31 suz Exp $
+
+<200403>
+2004-03-04 SUZUKI, Shinsuke <suz@crl.hitachi.co.jp>
+ * freebsd4/sys/netinet/tcp*.c:
+ FreeBSD Security Advisory: FreeBSD-SA-04:04.tcp
<200402>
2004-02-28 JINMEI, Tatuya <jinmei@isl.rdc.toshiba.co.jp>
View
37 freebsd4/sys/netinet/tcp_input.c
@@ -124,6 +124,24 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW,
&drop_synfin, 0, "Drop TCP packets with SYN+FIN set");
#endif
+SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0,
+ "TCP Segment Reassembly Queue");
+
+int tcp_reass_maxseg = 0;
+SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RD,
+ &tcp_reass_maxseg, 0,
+ "Global maximum number of TCP Segments in Reassembly Queue");
+
+int tcp_reass_qsize = 0;
+SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
+ &tcp_reass_qsize, 0,
+ "Global number of TCP Segments currently in Reassembly Queue");
+
+static int tcp_reass_overflows = 0;
+SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
+ &tcp_reass_overflows, 0,
+ "Global number of TCP Segment Reassembly Queue Overflows");
+
struct inpcbhead tcb;
#define tcb6 tcb /* for KAME src sync over BSD*'s */
struct inpcbinfo tcbinfo;
@@ -194,6 +212,21 @@ tcp_reass(tp, th, tlenp, m)
if (th == 0)
goto present;
+ /*
+ * Limit the number of segments in the reassembly queue to prevent
+ * holding on to too many segments (and thus running out of mbufs).
+ * Make sure to let the missing segment through which caused this
+ * queue. Always keep one global queue entry spare to be able to
+ * process the missing segment.
+ */
+ if (th->th_seq != tp->rcv_nxt &&
+ tcp_reass_qsize + 1 >= tcp_reass_maxseg) {
+ tcp_reass_overflows++;
+ tcpstat.tcps_rcvmemdrop++;
+ m_freem(m);
+ return (0);
+ }
+
/* Allocate a new queue entry. If we can't, just drop the pkt. XXX */
MALLOC(te, struct tseg_qent *, sizeof(struct tseg_qent), M_TSEGQ,
M_NOWAIT);
@@ -202,6 +235,7 @@ tcp_reass(tp, th, tlenp, m)
m_freem(m);
return (0);
}
+ tcp_reass_qsize++;
/*
* Find a segment which begins after this one does.
@@ -227,6 +261,7 @@ tcp_reass(tp, th, tlenp, m)
tcpstat.tcps_rcvdupbyte += *tlenp;
m_freem(m);
free(te, M_TSEGQ);
+ tcp_reass_qsize--;
/*
* Try to present any queued data
* at the left window edge to the user.
@@ -262,6 +297,7 @@ tcp_reass(tp, th, tlenp, m)
LIST_REMOVE(q, tqe_q);
m_freem(q->tqe_m);
free(q, M_TSEGQ);
+ tcp_reass_qsize--;
q = nq;
}
@@ -296,6 +332,7 @@ tcp_reass(tp, th, tlenp, m)
else
sbappend(&so->so_rcv, q->tqe_m);
free(q, M_TSEGQ);
+ tcp_reass_qsize--;
q = nq;
} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
ND6_HINT(tp);
View
7 freebsd4/sys/netinet/tcp_subr.c
@@ -243,6 +243,11 @@ tcp_init()
&tcbinfo.porthashmask);
tcbinfo.ipi_zone = zinit("tcpcb", sizeof(struct inp_tp), maxsockets,
ZONE_INTERRUPT, 0);
+
+ tcp_reass_maxseg = nmbclusters / 16;
+ TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments",
+ &tcp_reass_maxseg);
+
#ifdef INET6
#define TCP_MINPROTOHDR (sizeof(struct ip6_hdr) + sizeof(struct tcphdr))
#else /* INET6 */
@@ -757,6 +762,7 @@ tcp_close(tp)
LIST_REMOVE(q, tqe_q);
m_freem(q->tqe_m);
FREE(q, M_TSEGQ);
+ tcp_reass_qsize--;
}
inp->inp_ppcb = NULL;
soisdisconnected(so);
@@ -794,6 +800,7 @@ tcp_drain()
LIST_REMOVE(te, tqe_q);
m_freem(te->tqe_m);
FREE(te, M_TSEGQ);
+ tcp_reass_qsize--;
}
}
}
View
2 freebsd4/sys/netinet/tcp_var.h
@@ -53,6 +53,8 @@ struct tseg_qent {
struct mbuf *tqe_m; /* mbuf contains packet */
};
LIST_HEAD(tsegqe_head, tseg_qent);
+extern int tcp_reass_maxseg;
+extern int tcp_reass_qsize;
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_TSEGQ);
#endif

0 comments on commit f09af18

Please sign in to comment.
Something went wrong with that request. Please try again.