diff options
author | silby <silby@FreeBSD.org> | 2004-04-26 02:56:31 +0000 |
---|---|---|
committer | silby <silby@FreeBSD.org> | 2004-04-26 02:56:31 +0000 |
commit | 051b00be736964ed5c26256aa18bbe6c68ff7922 (patch) | |
tree | 8547bca0216e4f6983cf0489c681b37bfc557456 /sys/netinet/tcp_reass.c | |
parent | 312f49a25bec22bb547a39de59b639f0967847a5 (diff) | |
download | FreeBSD-src-051b00be736964ed5c26256aa18bbe6c68ff7922.zip FreeBSD-src-051b00be736964ed5c26256aa18bbe6c68ff7922.tar.gz |
Tighten up reset handling in order to make reset attacks as difficult as
possible while maintaining compatibility with the widest range of TCP stacks.
The algorithm is as follows:
---
For connections in the ESTABLISHED state, only resets with
sequence numbers exactly matching last_ack_sent will cause a reset,
all other segments will be silently dropped.
For connections in all other states, a reset anywhere in the window
will cause the connection to be reset. All other segments will be
silently dropped.
---
The necessity of accepting all in-window resets was discovered
by jayanth and jlemon, both of whom have seen TCP stacks that
will respond to FIN-ACK packets with resets not meeting the
strict last_ack_sent check.
Idea by: Darren Reed
Reviewed by: truckman, jlemon, others(?)
Diffstat (limited to 'sys/netinet/tcp_reass.c')
-rw-r--r-- | sys/netinet/tcp_reass.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 90cda71..d0c1f9b 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -1532,6 +1532,12 @@ trimthenstep6: * echo of our outgoing acknowlegement numbers, but some hosts * send a reset with the sequence number at the rightmost edge * of our receive window, and we have to handle this case. + * Note 2: Paul Watson's paper "Slipping in the Window" has shown + * that brute force RST attacks are possible. To combat this, + * we use a much stricter check while in the ESTABLISHED state, + * only accepting RSTs where the sequence number is equal to + * last_ack_sent. In all other states (the states in which a + * RST is more likely), the more permissive check is used. * If we have multiple segments in flight, the intial reset * segment sequence numbers will be to the left of last_ack_sent, * but they will eventually catch up. @@ -1570,6 +1576,10 @@ trimthenstep6: goto close; case TCPS_ESTABLISHED: + if (tp->last_ack_sent != th->th_seq) { + tcpstat.tcps_badrst++; + goto drop; + } case TCPS_FIN_WAIT_1: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: |