svn commit: r368183 - stable/11/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Mon Nov 30 10:58:07 UTC 2020
Author: tuexen
Date: Mon Nov 30 10:58:06 2020
New Revision: 368183
URL: https://svnweb.freebsd.org/changeset/base/368183
Log:
MFC r367530:
RFC 7323 specifies that:
* TCP segments without timestamps should be dropped when support for
the timestamp option has been negotiated.
* TCP segments with timestamps should be processed normally if support
for the timestamp option has not been negotiated.
This patch enforces the above.
Manually resolved merge conflicts.
MFC 367891:
Fix an issue I introuced in r367530: tcp_twcheck() can be called
with to == NULL for SYN segments. So don't assume tp != NULL.
Thanks to jhb@ for reporting and suggesting a fix.
MFC r367946:
Fix two occurences of a typo in a comment introduced in r367530.
Thanks to lstewart@ for reporting them.
PR: 250499
Reviewed by: gnn, rrs
Sponsored by: Netflix, Inc.
Differential Revision: https://reviews.freebsd.org/D27148
Modified:
stable/11/sys/netinet/tcp_input.c
stable/11/sys/netinet/tcp_syncache.c
stable/11/sys/netinet/tcp_timewait.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/netinet/tcp_input.c
==============================================================================
--- stable/11/sys/netinet/tcp_input.c Mon Nov 30 09:47:53 2020 (r368182)
+++ stable/11/sys/netinet/tcp_input.c Mon Nov 30 10:58:06 2020 (r368183)
@@ -992,8 +992,8 @@ relocked:
}
INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
- if (thflags & TH_SYN)
- tcp_dooptions(&to, optp, optlen, TO_SYN);
+ tcp_dooptions(&to, optp, optlen,
+ (thflags & TH_SYN) ? TO_SYN : 0);
/*
* NB: tcp_twcheck unlocks the INP and frees the mbuf.
*/
@@ -1729,20 +1729,29 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
}
/*
- * If timestamps were negotiated during SYN/ACK they should
- * appear on every segment during this session and vice versa.
+ * If timestamps were negotiated during SYN/ACK and a
+ * segment without a timestamp is received, silently drop
+ * the segment.
+ * See section 3.2 of RFC 7323.
*/
if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) {
if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
log(LOG_DEBUG, "%s; %s: Timestamp missing, "
- "no action\n", s, __func__);
+ "segment silently dropped\n", s, __func__);
free(s, M_TCPLOG);
}
+ goto drop;
}
+ /*
+ * If timestamps were not negotiated during SYN/ACK and a
+ * segment with a timestamp is received, ignore the
+ * timestamp and process the packet normally.
+ * See section 3.2 of RFC 7323.
+ */
if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) {
if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
log(LOG_DEBUG, "%s; %s: Timestamp not expected, "
- "no action\n", s, __func__);
+ "segment processed normally\n", s, __func__);
free(s, M_TCPLOG);
}
}
Modified: stable/11/sys/netinet/tcp_syncache.c
==============================================================================
--- stable/11/sys/netinet/tcp_syncache.c Mon Nov 30 09:47:53 2020 (r368182)
+++ stable/11/sys/netinet/tcp_syncache.c Mon Nov 30 10:58:06 2020 (r368183)
@@ -1111,6 +1111,40 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt
}
/*
+ * If timestamps were not negotiated during SYN/ACK and a
+ * segment with a timestamp is received, ignore the
+ * timestamp and process the packet normally.
+ * See section 3.2 of RFC 7323.
+ */
+ if (!(sc->sc_flags & SCF_TIMESTAMP) &&
+ (to->to_flags & TOF_TS)) {
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Timestamp not "
+ "expected, segment processed normally\n",
+ s, __func__);
+ free(s, M_TCPLOG);
+ s = NULL;
+ }
+ }
+
+ /*
+ * If timestamps were negotiated during SYN/ACK and a
+ * segment without a timestamp is received, silently drop
+ * the segment.
+ * See section 3.2 of RFC 7323.
+ */
+ if ((sc->sc_flags & SCF_TIMESTAMP) &&
+ !(to->to_flags & TOF_TS)) {
+ SCH_UNLOCK(sch);
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Timestamp missing, "
+ "segment silently dropped\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
+ return (-1); /* Do not send RST */
+ }
+
+ /*
* Pull out the entry to unlock the bucket row.
*
* NOTE: We must decrease TCPS_SYN_RECEIVED count here, not
@@ -1153,32 +1187,6 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt
log(LOG_DEBUG, "%s; %s: SEQ %u != IRS+1 %u, segment "
"rejected\n", s, __func__, th->th_seq, sc->sc_irs);
goto failed;
- }
-
- /*
- * If timestamps were not negotiated during SYN/ACK they
- * must not appear on any segment during this session.
- */
- if (!(sc->sc_flags & SCF_TIMESTAMP) && (to->to_flags & TOF_TS)) {
- if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
- log(LOG_DEBUG, "%s; %s: Timestamp not expected, "
- "segment rejected\n", s, __func__);
- goto failed;
- }
-
- /*
- * If timestamps were negotiated during SYN/ACK they should
- * appear on every segment during this session.
- * XXXAO: This is only informal as there have been unverified
- * reports of non-compliants stacks.
- */
- if ((sc->sc_flags & SCF_TIMESTAMP) && !(to->to_flags & TOF_TS)) {
- if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
- log(LOG_DEBUG, "%s; %s: Timestamp missing, "
- "no action\n", s, __func__);
- free(s, M_TCPLOG);
- s = NULL;
- }
}
*lsop = syncache_socket(sc, *lsop, m);
Modified: stable/11/sys/netinet/tcp_timewait.c
==============================================================================
--- stable/11/sys/netinet/tcp_timewait.c Mon Nov 30 09:47:53 2020 (r368182)
+++ stable/11/sys/netinet/tcp_timewait.c Mon Nov 30 10:58:06 2020 (r368183)
@@ -373,9 +373,10 @@ tcp_twstart(struct tcpcb *tp)
/*
* Returns 1 if the TIME_WAIT state was killed and we should start over,
* looking for a pcb in the listen state. Returns 0 otherwise.
+ * It be called with to == NULL only for pure SYN-segments.
*/
int
-tcp_twcheck(struct inpcb *inp, struct tcpopt *to __unused, struct tcphdr *th,
+tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
struct mbuf *m, int tlen)
{
struct tcptw *tw;
@@ -396,6 +397,8 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to __unu
goto drop;
thflags = th->th_flags;
+ KASSERT(to != NULL || (thflags & (TH_SYN | TH_ACK)) == TH_SYN,
+ ("tcp_twcheck: called without options on a non-SYN segment"));
/*
* NOTE: for FIN_WAIT_2 (to be added later),
@@ -443,6 +446,16 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to __unu
*/
if ((thflags & TH_ACK) == 0)
goto drop;
+
+ /*
+ * If timestamps were negotiated during SYN/ACK and a
+ * segment without a timestamp is received, silently drop
+ * the segment.
+ * See section 3.2 of RFC 7323.
+ */
+ if (((to->to_flags & TOF_TS) == 0) && (tw->t_recent != 0)) {
+ goto drop;
+ }
/*
* Reset the 2MSL timer if this is a duplicate FIN.
More information about the svn-src-stable
mailing list