Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Sep 2024 20:09:56 GMT
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: cbc9438f0505 - main - tcp: improve ref count handling when processing SYN
Message-ID:  <202409282009.48SK9uZc065748@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by tuexen:

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

commit cbc9438f0505bd971e9eba635afdae38a267d76e
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2024-09-28 20:06:41 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2024-09-28 20:06:41 +0000

    tcp: improve ref count handling when processing SYN
    
    Don't leak a reference count for so->so_cred when processing an
    incoming SYN segment with an on-stack syncache entry and the
    sysctl variable net.inet.tcp.syncache.see_other is false.
    
    Reviewed by:            cc, markj, rscheff
    MFC after:              1 week
    Sponsored by:           Netflix, Inc.
    Pull Request:           https://reviews.freebsd.org/D46793
---
 sys/netinet/tcp_syncache.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index ed131421207d..19145446988e 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1375,7 +1375,6 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 	struct label *maclabel = NULL;
 #endif
 	struct syncache scs;
-	struct ucred *cred;
 	uint64_t tfo_response_cookie;
 	unsigned int *tfo_pending = NULL;
 	int tfo_cookie_valid = 0;
@@ -1392,7 +1391,6 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 	 */
 	KASSERT(SOLISTENING(so), ("%s: %p not listening", __func__, so));
 	tp = sototcpcb(so);
-	cred = V_tcp_syncache.see_other ? NULL : crhold(so->so_cred);
 
 #ifdef INET6
 	if (inc->inc_flags & INC_ISIPV6) {
@@ -1623,9 +1621,21 @@ skip_alloc:
 #ifdef MAC
 	sc->sc_label = maclabel;
 #endif
-	sc->sc_cred = cred;
+	/*
+	 * sc_cred is only used in syncache_pcblist() to list TCP endpoints in
+	 * TCPS_SYN_RECEIVED state when V_tcp_syncache.see_other is false.
+	 * Therefore, store the credentials and take a reference count only
+	 * when needed:
+	 * - sc is allocated from the zone and not using the on stack instance.
+	 * - the sysctl variable net.inet.tcp.syncache.see_other is false.
+	 * The reference count is decremented when a zone allocated sc is
+	 * freed in syncache_free().
+	 */
+	if (sc != &scs && !V_tcp_syncache.see_other)
+		sc->sc_cred = crhold(so->so_cred);
+	else
+		sc->sc_cred = NULL;
 	sc->sc_port = port;
-	cred = NULL;
 	sc->sc_ipopts = ipopts;
 	bcopy(inc, &sc->sc_inc, sizeof(struct in_conninfo));
 	sc->sc_ip_tos = ip_tos;
@@ -1761,8 +1771,6 @@ donenoprobe:
 		tcp_fastopen_decrement_counter(tfo_pending);
 
 tfo_expanded:
-	if (cred != NULL)
-		crfree(cred);
 	if (sc == NULL || sc == &scs) {
 #ifdef MAC
 		mac_syncache_destroy(&maclabel);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202409282009.48SK9uZc065748>