Date: Thu, 1 Jun 2017 14:58:26 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r319431 - in stable/11/sys/netinet: . tcp_stacks Message-ID: <201706011458.v51EwQ3v082894@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Thu Jun 1 14:58:26 2017 New Revision: 319431 URL: https://svnweb.freebsd.org/changeset/base/319431 Log: When a SYN-ACK is received in SYN-SENT state, RFC 793 requires the validation of SEG.ACK as the first step. If the ACK is not acceptable, a RST segment should be sent and the segment should be dropped. Up to now, the segment was partially processed. This patch moves the check for the SEG.ACK validation up to the front as required. Reviewed by: hiren, gnn Differential Revision: https://reviews.freebsd.org/D10424 Modified: stable/11/sys/netinet/tcp_input.c stable/11/sys/netinet/tcp_stacks/fastpath.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/netinet/tcp_input.c ============================================================================== --- stable/11/sys/netinet/tcp_input.c Thu Jun 1 14:49:53 2017 (r319430) +++ stable/11/sys/netinet/tcp_input.c Thu Jun 1 14:58:26 2017 (r319431) @@ -1607,6 +1607,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru } /* + * If a segment with the ACK-bit set arrives in the SYN-SENT state + * check SEQ.ACK first. + */ + if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && + (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { + rstreason = BANDLIM_UNLIMITED; + goto dropwithreset; + } + + /* * Segment received on connection. * Reset idle time and keep-alive timer. * XXX: This should be done after segment @@ -1984,7 +1994,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru /* * 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. * if seg does not contain SYN, then drop it. * Otherwise this is an acceptable SYN segment @@ -1997,12 +2006,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru * continue processing rest of data/controls, beginning with URG */ case TCPS_SYN_SENT: - if ((thflags & TH_ACK) && - (SEQ_LEQ(th->th_ack, tp->iss) || - SEQ_GT(th->th_ack, tp->snd_max))) { - rstreason = BANDLIM_UNLIMITED; - goto dropwithreset; - } if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) { TCP_PROBE5(connect__refused, NULL, tp, m, tp, th); Modified: stable/11/sys/netinet/tcp_stacks/fastpath.c ============================================================================== --- stable/11/sys/netinet/tcp_stacks/fastpath.c Thu Jun 1 14:49:53 2017 (r319430) +++ stable/11/sys/netinet/tcp_stacks/fastpath.c Thu Jun 1 14:58:26 2017 (r319431) @@ -485,7 +485,6 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, str /* * 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. * if seg does not contain SYN, then drop it. * Otherwise this is an acceptable SYN segment @@ -498,12 +497,6 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, str * continue processing rest of data/controls, beginning with URG */ case TCPS_SYN_SENT: - if ((thflags & TH_ACK) && - (SEQ_LEQ(th->th_ack, tp->iss) || - SEQ_GT(th->th_ack, tp->snd_max))) { - rstreason = BANDLIM_UNLIMITED; - goto dropwithreset; - } if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) { TCP_PROBE5(connect__refused, NULL, tp, m, tp, th); tp = tcp_drop(tp, ECONNREFUSED); @@ -1744,6 +1737,20 @@ tcp_do_segment_fastslow(struct mbuf *m, struct tcphdr m_freem(m); return; } + + /* + * If a segment with the ACK-bit set arrives in the SYN-SENT state + * check SEQ.ACK first. + */ + if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && + (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { + tcp_dropwithreset(m, th, tp, tlen, BANDLIM_UNLIMITED); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); + } + INP_WUNLOCK(tp->t_inpcb); + return; + } tp->sackhint.last_sack_ack = 0; @@ -2203,6 +2210,20 @@ tcp_do_segment_fastack(struct mbuf *m, struct tcphdr * return; } + /* + * If a segment with the ACK-bit set arrives in the SYN-SENT state + * check SEQ.ACK first. + */ + if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && + (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { + tcp_dropwithreset(m, th, tp, tlen, BANDLIM_UNLIMITED); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); + } + INP_WUNLOCK(tp->t_inpcb); + return; + } + tp->sackhint.last_sack_ack = 0; /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706011458.v51EwQ3v082894>