summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>1998-03-18 02:37:50 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>1998-03-18 02:37:50 +0000
commitfba1cb914730e27df0cf27efce0189e2a50f5a3d (patch)
tree938cf1998cc54630761f0a843c7e3fedd1b46e73
parent193a51c4f31fbda0a6b7e185345494caaf5a73e1 (diff)
Add FreeBSD patch (check for SYN packets arriving at a socket in
LISTEN state with source address/port == destination address/port).
-rw-r--r--sys/netinet/tcp_input.c33
-rw-r--r--sys/netinet/tcp_var.h3
2 files changed, 28 insertions, 8 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 9138f15d703..e6d4a443d89 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.17 1997/11/12 20:59:44 deraadt Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.18 1998/03/18 02:37:47 angelos Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -740,6 +740,7 @@ findpcb:
* If the state is LISTEN then ignore segment if it contains an RST.
* If the segment contains an ACK then it is bad and send a RST.
* If it does not contain a SYN then it is not interesting; drop it.
+ * If it is from this socket, drop it, it must be forged.
* Don't bother responding if the destination was a broadcast.
* Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
* tp->iss, and send a segment:
@@ -759,6 +760,9 @@ findpcb:
goto dropwithreset;
if ((tiflags & TH_SYN) == 0)
goto drop;
+ if ((ti->ti_dport == ti->ti_sport) &&
+ (ti->ti_dst.s_addr == ti->ti_src.s_addr))
+ goto drop;
#ifdef TCPCOOKIE
/*
@@ -836,6 +840,24 @@ findpcb:
}
/*
+ * If the state is SYN_RECEIVED:
+ * if seg contains SYN/ACK, send an RST.
+ * if seg contains an ACK, but not for our SYN/ACK, send an RST
+ */
+
+ case TCPS_SYN_RECEIVED:
+ if (tiflags & TH_ACK) {
+ if (tiflags & TH_SYN) {
+ tcpstat.tcps_badsyn++;
+ goto dropwithreset;
+ }
+ if (SEQ_LEQ(ti->ti_ack, tp->snd_una) ||
+ SEQ_GT(ti->ti_ack, tp->snd_max))
+ goto dropwithreset;
+ }
+ break;
+
+ /*
* If the state is SYN_SENT:
* if seg contains an ACK, but not for our SYN, drop the input.
* if seg contains a RST, then drop the connection.
@@ -1108,14 +1130,11 @@ trimthenstep6:
switch (tp->t_state) {
/*
- * In SYN_RECEIVED state if the ack ACKs our SYN then enter
- * ESTABLISHED state and continue processing, otherwise
- * send an RST.
+ * In SYN_RECEIVED state, the ack ACKs our SYN, so enter
+ * ESTABLISHED state and continue processing.
+ * The ACK was checked above.
*/
case TCPS_SYN_RECEIVED:
- if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
- SEQ_GT(ti->ti_ack, tp->snd_max))
- goto dropwithreset;
tcpstat.tcps_connects++;
soisconnected(so);
tp->t_state = TCPS_ESTABLISHED;
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index db09a476bd5..89c24a90815 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.9 1998/01/24 18:21:39 mickey Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.10 1998/03/18 02:37:49 angelos Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -225,6 +225,7 @@ struct tcpstat {
u_long tcps_pcbhashmiss; /* input packets missing pcb hash */
u_long tcps_noport; /* no socket on port */
+ u_long tcps_badsyn; /* SYN packet with src==dst rcv'ed */
};
/*