The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=b712bb84a7a7dc229324a95170b8a77e0d9c5bec
commit b712bb84a7a7dc229324a95170b8a77e0d9c5bec Author: Gleb Smirnoff <[email protected]> AuthorDate: 2026-09-07 19:09:40 +0000 Commit: Gleb Smirnoff <[email protected]> CommitDate: 2026-09-07 19:09:40 +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 --- 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 44288d8f344d..2320d6901fac 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2455,7 +2455,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 33f62a73ce2c..ff046c7ad7de 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -209,6 +209,7 @@ tcp_usr_detach(struct socket *so) tp->t_state < TCPS_SYN_SENT, ("%s: inp %p not disconnected or embryonic", __func__, inp)); + TCPSTATES_DEC(tp->t_state); tcp_discardcb(tp); in_pcbfree(inp); }
