mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
tcp: improve credential handling in syncache
When adding a syncache entry, take a reference count of the
credentials while the inp is still locked.
Thanks to markj@ for providing a hint regarding the root cause.
Reported by: David Marker
Reviewed by: glebius
Tested by: David Marker
Fixes: cbc9438f05 ("tcp: improve ref count handling when processing SYN")
MFC after: 3 days
Sponsored by: Netflix, Inc.
Differential Revision: https://reviews.freebsd.org/D53380
This commit is contained in:
1 parent
8a25a04058
commit
44cb1e857f
1 file changed
+9
-5
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user