diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 1998-03-18 02:37:50 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 1998-03-18 02:37:50 +0000 |
commit | fba1cb914730e27df0cf27efce0189e2a50f5a3d (patch) | |
tree | 938cf1998cc54630761f0a843c7e3fedd1b46e73 /sys | |
parent | 193a51c4f31fbda0a6b7e185345494caaf5a73e1 (diff) |
Add FreeBSD patch (check for SYN packets arriving at a socket in
LISTEN state with source address/port == destination address/port).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_input.c | 33 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 3 |
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 */ }; /* |