git: b7118461f909 - main - tcp: improve segment validation in SYN-RECEIVED
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 02 Oct 2025 14:54:27 UTC
The branch main has been updated by tuexen:
URL: https://cgit.FreeBSD.org/src/commit/?id=b7118461f9099876cb2c2923948f8fb647defd57
commit b7118461f9099876cb2c2923948f8fb647defd57
Author: Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2025-10-02 14:51:09 +0000
Commit: Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2025-10-02 14:51:09 +0000
tcp: improve segment validation in SYN-RECEIVED
The validation of SEG.SEQ (first step in SEGMENT ARRIVES of RFC 9293)
should be done before the validation of SEG.ACK (fifth step in
SEGMENT ARRIVES in RFC 9293).
Furthermore, when the SEG.SEQ validation fails, a challenge ACK
should be sent instead of sending a RST-segment and moving the
endpoint to CLOSED.
Reported by: Tilnel on freebsd-net
Reviewed by: Nick Banks
MFC after: 3 days
Sponsored by: Netflix, Inc.
Differential Revision: https://reviews.freebsd.org/D52849
---
sys/netinet/tcp_syncache.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 778ab0583735..7f842512858d 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1258,19 +1258,6 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
}
}
- /*
- * SEG.ACK validation:
- * SEG.ACK must match our initial send sequence number + 1.
- */
- if (th->th_ack != sc->sc_iss + 1) {
- SCH_UNLOCK(sch);
- if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
- log(LOG_DEBUG, "%s; %s: ACK %u != ISS+1 %u, "
- "segment rejected\n",
- s, __func__, th->th_ack, sc->sc_iss + 1);
- goto failed;
- }
-
/*
* SEG.SEQ validation:
* The SEG.SEQ must be in the window starting at our
@@ -1278,11 +1265,26 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
*/
if (SEQ_LEQ(th->th_seq, sc->sc_irs) ||
SEQ_GT(th->th_seq, sc->sc_irs + sc->sc_wnd)) {
- SCH_UNLOCK(sch);
if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
log(LOG_DEBUG, "%s; %s: SEQ %u != IRS+1 %u, "
- "segment rejected\n",
+ "sending challenge ACK\n",
s, __func__, th->th_seq, sc->sc_irs + 1);
+ syncache_send_challenge_ack(sc, m);
+ SCH_UNLOCK(sch);
+ free(s, M_TCPLOG);
+ return (-1); /* Do not send RST */;
+ }
+
+ /*
+ * SEG.ACK validation:
+ * SEG.ACK must match our initial send sequence number + 1.
+ */
+ if (th->th_ack != sc->sc_iss + 1) {
+ SCH_UNLOCK(sch);
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
+ log(LOG_DEBUG, "%s; %s: ACK %u != ISS+1 %u, "
+ "segment rejected\n",
+ s, __func__, th->th_ack, sc->sc_iss + 1);
goto failed;
}