git: 7b4bc013b179 - stable/15 - tcp: fix TCPS_CLOSED state underleak in syncache_socket()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 24 Sep 2026 03:33:33 UTC
The branch stable/15 has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=7b4bc013b179ab067e9c6212279078b24c11c60c
commit 7b4bc013b179ab067e9c6212279078b24c11c60c
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2026-09-07 19:09:40 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2026-09-24 03:32:49 +0000
tcp: fix TCPS_CLOSED state underleak in syncache_socket()
The syncache entry holds one TCPS_SYN_RECEIVED count that normally is
transferred to the the newborn tp. Upon failure syncache_socket() shall
not use TCPSTATES_INC/TCPSTATES_DEC (see 5050df3f4aa4 why). But when
syncache_socket() fails in_pcbconnect(), it calls tcp_discardcb() to free
resources that were just allocated by tcp_newtcpcb() and this
tcp_discardcb() would do TCPSTATES_DEC(tp->t_state). The t_state is
TCPS_CLOSED at this point.
Make tcp_discardcb() symmetrical to tcp_newtcpcb() - not responsible for
the TCPSTATES. Make the caller responsible for state count book keeping.
Reviewed by: tuexen
Fixes: 3703e1a73e0e0367c04f47f793e46495e46e647b
Differential Revision: https://reviews.freebsd.org/D59325
(cherry picked from commit b712bb84a7a7dc229324a95170b8a77e0d9c5bec)
---
sys/netinet/tcp_subr.c | 1 -
sys/netinet/tcp_usrreq.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index d8e58fe3eff1..663042cd8c93 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2447,7 +2447,6 @@ tcp_discardcb(struct tcpcb *tp)
STAILQ_FOREACH_FROM_SAFE(m, &tp->t_inqueue, m_stailqpkt, prev)
m_freem(m);
}
- TCPSTATES_DEC(tp->t_state);
if (tp->t_fb->tfb_tcp_fb_fini)
(*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 4d1a6455d09e..6b2388b9363c 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -208,6 +208,7 @@ tcp_usr_detach(struct socket *so)
tp->t_state < TCPS_SYN_SENT,
("%s: inp %p not dropped or embryonic", __func__, inp));
+ TCPSTATES_DEC(tp->t_state);
tcp_discardcb(tp);
in_pcbfree(inp);
}