git: c9cd686bd4a0 - main - tcp: drop data received after a FIN has been processed

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Thu, 18 Apr 2024 20:21:35 UTC
The branch main has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=c9cd686bd4a039c652ed5d11019bae10828329df

commit c9cd686bd4a039c652ed5d11019bae10828329df
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2024-04-18 19:50:31 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2024-04-18 19:54:42 +0000

    tcp: drop data received after a FIN has been processed
    
    RFC 9293 describes the handling of data in the CLOSE-WAIT, CLOSING,
    LAST-ACK, and TIME-WAIT states:
    This should not occur since a FIN has been received from the remote
    side. Ignore the segment text.
    Therefore, implement this handling.
    
    Reviewed by:            rrs, rscheff
    MFC after:              3 days
    Sponsored by:           Netflix, Inc.
    Differential Revision:  https://reviews.freebsd.org/D44746
---
 sys/netinet/tcp_input.c       |  6 ++++--
 sys/netinet/tcp_stacks/bbr.c  | 18 ------------------
 sys/netinet/tcp_stacks/rack.c | 14 --------------
 3 files changed, 4 insertions(+), 34 deletions(-)

diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 1c6bdedc9368..3fda6e903738 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -2337,9 +2337,11 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
 
 	/*
 	 * If new data are received on a connection after the
-	 * user processes are gone, then RST the other end.
+	 * user processes are gone, then RST the other end if
+	 * no FIN has been processed.
 	 */
-	if ((tp->t_flags & TF_CLOSED) && tlen) {
+	if ((tp->t_flags & TF_CLOSED) && tlen > 0 &&
+	    TCPS_HAVERCVDFIN(tp->t_state) == 0) {
 		if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
 			log(LOG_DEBUG, "%s; %s: %s: Received %d bytes of data "
 			    "after socket was closed, "
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index 06e80db4a0eb..946b65cda6a5 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -9555,15 +9555,6 @@ bbr_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so,
 	if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
 		return (ret_val);
 	}
-	/*
-	 * If new data are received on a connection after the user processes
-	 * are gone, then RST the other end.
-	 * We call a new function now so we might continue and setup
-	 * to reset at all data being ack'd.
-	 */
-	if ((tp->t_flags & TF_CLOSED) && tlen &&
-	    bbr_check_data_after_close(m, bbr, tp, &tlen, th, so))
-		return (1);
 	/*
 	 * If last ACK falls within this segment's sequence numbers, record
 	 * its timestamp. NOTE: 1) That the test incorporates suggestions
@@ -9666,15 +9657,6 @@ bbr_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so,
 	if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
 		return (ret_val);
 	}
-	/*
-	 * If new data are received on a connection after the user processes
-	 * are gone, then RST the other end.
-	 * We call a new function now so we might continue and setup
-	 * to reset at all data being ack'd.
-	 */
-	if ((tp->t_flags & TF_CLOSED) && tlen &&
-	    bbr_check_data_after_close(m, bbr, tp, &tlen, th, so))
-		return (1);
 	/*
 	 * If last ACK falls within this segment's sequence numbers, record
 	 * its timestamp. NOTE: 1) That the test incorporates suggestions
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 5b76480ee55d..409402adb907 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -14997,13 +14997,6 @@ rack_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so,
 			      &rack->r_ctl.challenge_ack_cnt)) {
 		return (ret_val);
 	}
-	/*
-	 * If new data are received on a connection after the user processes
-	 * are gone, then RST the other end.
-	 */
-	if ((tp->t_flags & TF_CLOSED) && tlen &&
-	    rack_check_data_after_close(m, tp, &tlen, th, so))
-		return (1);
 	/*
 	 * If last ACK falls within this segment's sequence numbers, record
 	 * its timestamp. NOTE: 1) That the test incorporates suggestions
@@ -15112,13 +15105,6 @@ rack_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so,
 			      &rack->r_ctl.challenge_ack_cnt)) {
 		return (ret_val);
 	}
-	/*
-	 * If new data are received on a connection after the user processes
-	 * are gone, then RST the other end.
-	 */
-	if ((tp->t_flags & TF_CLOSED) && tlen &&
-	    rack_check_data_after_close(m, tp, &tlen, th, so))
-		return (1);
 	/*
 	 * If last ACK falls within this segment's sequence numbers, record
 	 * its timestamp. NOTE: 1) That the test incorporates suggestions