View | Details | Raw Unified | Return to bug 7892
Collapse All | Expand All

(-)tcp_input.c (-42 / +112 lines)
Lines 979-995 Link Here
979
979
980
	/*
980
	/*
981
	 * States other than LISTEN or SYN_SENT.
981
	 * States other than LISTEN or SYN_SENT.
982
	 * First check timestamp, if present.
982
	 * First check the RST flag and sequence number since reset segments
983
	 * are exempt from the timestamp and connection count tests.  This
984
	 * fixes a bug introduced by the Stevens, vol. 2, p. 960 bugfix
985
	 * below which allowed reset segments in half the sequence space
986
	 * to fall though and be processed (which gives forged reset
987
	 * segments with a random sequence number a 50 percent chance of
988
	 * killing a connection).
989
	 * Then check timestamp, if present.
983
	 * Then check the connection count, if present.
990
	 * Then check the connection count, if present.
984
	 * Then check that at least some bytes of segment are within
991
	 * Then check that at least some bytes of segment are within
985
	 * receive window.  If segment begins before rcv_nxt,
992
	 * receive window.  If segment begins before rcv_nxt,
986
	 * drop leading data (and SYN); if nothing left, just ack.
993
	 * drop leading data (and SYN); if nothing left, just ack.
987
	 *
994
	 *
995
	 *
996
	 * If the RST bit is set, check the sequence number to see
997
	 * if this is a valid reset segment.
998
	 * RFC 793 page 37:
999
	 *   In all states except SYN-SENT, all reset (RST) segments
1000
	 *   are validated by checking their SEQ-fields.  A reset is
1001
	 *   valid if its sequence number is in the window.
1002
	 * Note: this does not take into account delayed ACKs, so
1003
	 *   we should test against last_ack_sent instead of rcv_nxt.
1004
	 *   Also, it does not make sense to allow reset segments with
1005
	 *   sequence numbers greater than last_ack_sent to be processed
1006
	 *   since these sequence numbers are just the acknowledgement
1007
	 *   numbers in our outgoing packets being echoed back at us,
1008
	 *   and these acknowledgement numbers are monotonically
1009
	 *   increasing.
1010
	 * If we have multiple segments in flight, the intial reset
1011
	 * segment sequence numbers will be to the left of last_ack_sent,
1012
	 * but they will eventually catch up.
1013
	 * In any case, it never made sense to trim reset segments to
1014
	 * fit the receive window since RFC 1122 says:
1015
	 *   4.2.2.12  RST Segment: RFC-793 Section 3.4
1016
	 *
1017
	 *    A TCP SHOULD allow a received RST segment to include data.
1018
	 *
1019
	 *    DISCUSSION
1020
	 *         It has been suggested that a RST segment could contain
1021
	 *         ASCII text that encoded and explained the cause of the
1022
	 *         RST.  No standard has yet been established for such
1023
	 *         data.
1024
	 *
1025
	 * If the reset segment passes the sequence number test examine
1026
	 * the state:
1027
	 *    SYN_RECEIVED STATE:
1028
	 *	If passive open, return to LISTEN state.
1029
	 *	If active open, inform user that connection was refused.
1030
	 *    ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
1031
	 *	Inform user that connection was reset, and close tcb.
1032
	 *    CLOSING, LAST_ACK, TIME_WAIT STATES
1033
	 *	Close the tcb.
1034
	 *    TIME_WAIT state:
1035
	 *	Drop the segment - see Stevens, vol. 2, p. 964 and
1036
	 *      RFC 1337.
1037
	 */
1038
	if (tiflags&TH_RST) {
1039
		if (tp->last_ack_sent == ti->ti_seq) {
1040
			switch (tp->t_state) {
1041
1042
			case TCPS_SYN_RECEIVED:
1043
				so->so_error = ECONNREFUSED;
1044
				goto close;
1045
1046
			case TCPS_ESTABLISHED:
1047
			case TCPS_FIN_WAIT_1:
1048
			case TCPS_FIN_WAIT_2:
1049
			case TCPS_CLOSE_WAIT:
1050
				so->so_error = ECONNRESET;
1051
			close:
1052
				tp->t_state = TCPS_CLOSED;
1053
				tcpstat.tcps_drops++;
1054
				tp = tcp_close(tp);
1055
				break;
1056
1057
			case TCPS_CLOSING:
1058
			case TCPS_LAST_ACK:
1059
				tp = tcp_close(tp);
1060
				break;
1061
1062
			case TCPS_TIME_WAIT:
1063
				break;
1064
			}
1065
		}
1066
		goto drop;
1067
	}
1068
1069
	/*
988
	 * RFC 1323 PAWS: If we have a timestamp reply on this segment
1070
	 * RFC 1323 PAWS: If we have a timestamp reply on this segment
989
	 * and it's less than ts_recent, drop it.
1071
	 * and it's less than ts_recent, drop it.
990
	 */
1072
	 */
991
	if ((to.to_flag & TOF_TS) != 0 && (tiflags & TH_RST) == 0 &&
1073
	if ((to.to_flag & TOF_TS) != 0 && tp->ts_recent &&
992
	    tp->ts_recent && TSTMP_LT(to.to_tsval, tp->ts_recent)) {
1074
	    TSTMP_LT(to.to_tsval, tp->ts_recent)) {
993
1075
994
		/* Check to see if ts_recent is over 24 days old.  */
1076
		/* Check to see if ts_recent is over 24 days old.  */
995
		if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
1077
		if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
Lines 1020-1029 Link Here
1020
	 *   RST segments do not have to comply with this.
1102
	 *   RST segments do not have to comply with this.
1021
	 */
1103
	 */
1022
	if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
1104
	if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
1023
	    ((to.to_flag & TOF_CC) == 0 || tp->cc_recv != to.to_cc) &&
1105
	    ((to.to_flag & TOF_CC) == 0 || tp->cc_recv != to.to_cc))
1024
	    (tiflags & TH_RST) == 0)
1025
 		goto dropafterack;
1106
 		goto dropafterack;
1026
1107
1108
	/*
1109
	 * In the SYN-RECEIVED state, validate that the packet belongs to
1110
	 * this connection before trimming the data to fit the receive
1111
	 * window.  Check the sequence number versus IRS since we know
1112
	 * the sequence numbers haven't wrapped.  This is a partial fix
1113
	 * for the "LAND" DoS attack.
1114
	 */
1115
	if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(ti->ti_seq, tp->irs))
1116
		goto dropwithreset;
1117
1027
	todrop = tp->rcv_nxt - ti->ti_seq;
1118
	todrop = tp->rcv_nxt - ti->ti_seq;
1028
	if (todrop > 0) {
1119
	if (todrop > 0) {
1029
		if (tiflags & TH_SYN) {
1120
		if (tiflags & TH_SYN) {
Lines 1135-1174 Link Here
1135
	}
1226
	}
1136
1227
1137
	/*
1228
	/*
1138
	 * If the RST bit is set examine the state:
1139
	 *    SYN_RECEIVED STATE:
1140
	 *	If passive open, return to LISTEN state.
1141
	 *	If active open, inform user that connection was refused.
1142
	 *    ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
1143
	 *	Inform user that connection was reset, and close tcb.
1144
	 *    CLOSING, LAST_ACK, TIME_WAIT STATES
1145
	 *	Close the tcb.
1146
	 */
1147
	if (tiflags&TH_RST) switch (tp->t_state) {
1148
1149
	case TCPS_SYN_RECEIVED:
1150
		so->so_error = ECONNREFUSED;
1151
		goto close;
1152
1153
	case TCPS_ESTABLISHED:
1154
	case TCPS_FIN_WAIT_1:
1155
	case TCPS_FIN_WAIT_2:
1156
	case TCPS_CLOSE_WAIT:
1157
		so->so_error = ECONNRESET;
1158
	close:
1159
		tp->t_state = TCPS_CLOSED;
1160
		tcpstat.tcps_drops++;
1161
		tp = tcp_close(tp);
1162
		goto drop;
1163
1164
	case TCPS_CLOSING:
1165
	case TCPS_LAST_ACK:
1166
	case TCPS_TIME_WAIT:
1167
		tp = tcp_close(tp);
1168
		goto drop;
1169
	}
1170
1171
	/*
1172
	 * If a SYN is in the window, then this is an
1229
	 * If a SYN is in the window, then this is an
1173
	 * error and we send an RST and drop the connection.
1230
	 * error and we send an RST and drop the connection.
1174
	 */
1231
	 */
Lines 1673-1681 Link Here
1673
	/*
1730
	/*
1674
	 * Generate an ACK dropping incoming segment if it occupies
1731
	 * Generate an ACK dropping incoming segment if it occupies
1675
	 * sequence space, where the ACK reflects our state.
1732
	 * sequence space, where the ACK reflects our state.
1676
	 */
1733
	 *
1677
	if (tiflags & TH_RST)
1734
	 * We can now skip the test for the RST flag since all
1678
		goto drop;
1735
	 * paths to this code happen after packets containing
1736
	 * RST have been dropped.
1737
	 *
1738
	 * In the SYN-RECEIVED state, don't send an ACK unless the
1739
	 * segment we received passes the SYN-RECEIVED ACK test.
1740
	 * If it fails send a RST.  This breaks the loop in the
1741
	 * "LAND" DoS attack, and also prevents an ACK storm
1742
	 * between two listening ports that have been sent forged
1743
	 * SYN segments, each with the source address of the other.
1744
	 */
1745
	if (tp->t_state == TCPS_SYN_RECEIVED && (tiflags & TH_ACK) &&
1746
	    (SEQ_GT(tp->snd_una, ti->ti_ack) ||
1747
	     SEQ_GT(ti->ti_ack, tp->snd_max)) )
1748
		goto dropwithreset;
1679
#ifdef TCPDEBUG
1749
#ifdef TCPDEBUG
1680
	if (so->so_options & SO_DEBUG)
1750
	if (so->so_options & SO_DEBUG)
1681
		tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
1751
		tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);

Return to bug 7892