diff options
Diffstat (limited to 'sys/netinet/tcp_syncache.c')
| -rw-r--r-- | sys/netinet/tcp_syncache.c | 14 | 
1 files changed, 9 insertions, 5 deletions
| diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 3cb538f7054d..3a7755e9f09e 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1380,6 +1380,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,  	struct tcpcb *tp;  	struct socket *rv = NULL;  	struct syncache *sc = NULL; +	struct ucred *cred;  	struct syncache_head *sch;  	struct mbuf *ipopts = NULL;  	u_int ltflags; @@ -1408,6 +1409,7 @@ 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) { @@ -1636,16 +1638,16 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,  	/*  	 * 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: +	 * Therefore, store the credentials 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 +	if (sc != &scs && !V_tcp_syncache.see_other) { +		sc->sc_cred = cred; +		cred = NULL; +	} else  		sc->sc_cred = NULL;  	sc->sc_port = port;  	sc->sc_ipopts = ipopts; @@ -1783,6 +1785,8 @@ 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); | 
