diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c --- a/sys/kern/uipc_ktls.c +++ b/sys/kern/uipc_ktls.c @@ -595,8 +595,6 @@ return (error); } -uint64_t ktls_glob_gen = 1; - static int ktls_create_session(struct socket *so, struct tls_enable *en, struct ktls_session **tlsp, int direction) @@ -821,8 +819,7 @@ arc4rand(tls->params.iv + 8, sizeof(uint64_t), 0); } - atomic_thread_fence_rel(); - tls->gen = atomic_fetchadd_64(&ktls_glob_gen, 1); + tls->gen = 0; *tlsp = tls; return (0); } @@ -865,8 +862,7 @@ memcpy(tls_new->params.cipher_key, tls->params.cipher_key, tls->params.cipher_key_len); - atomic_thread_fence_rel(); - tls_new->gen = atomic_fetchadd_64(&ktls_glob_gen, 1); + tls_new->gen = 0; return (tls_new); } @@ -1946,8 +1942,6 @@ MPASS(tls->refcount == 0); - atomic_add_acq_64(&ktls_glob_gen, 1); - inp = tls->inp; if (tls->tx) { wlocked = INP_WLOCKED(inp); diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2669,8 +2669,13 @@ #define SND_TAG_STATUS_MAXLEN 128 #ifdef KERN_TLS + +static struct sx ktlslist_lock; +SX_SYSINIT(ktlslistlock, &ktlslist_lock, "ktlslist"); +static uint64_t ktls_glob_gen = 1; + static int -tcp_ktlslist(SYSCTL_HANDLER_ARGS, bool export_keys) +tcp_ktlslist_locked(SYSCTL_HANDLER_ARGS, bool export_keys) { struct xinpgen xig; struct inpcb *inp; @@ -2684,6 +2689,7 @@ int error; bool ek, p; + sx_assert(&ktlslist_lock, SA_XLOCKED); if (req->newptr != NULL) return (EPERM); @@ -2692,7 +2698,7 @@ ipi_gencnt = V_tcbinfo.ipi_gencnt; bzero(&xig, sizeof(xig)); xig.xig_len = sizeof(xig); - xig.xig_gen = atomic_load_acq_64(&ktls_glob_gen); + xig.xig_gen = ktls_glob_gen++; xig.xig_sogen = so_gencnt; struct inpcb_iterator inpi = INP_ALL_ITERATOR(&V_tcbinfo, @@ -2708,7 +2714,8 @@ ek = export_keys && cr_canexport_ktlskeys( req->td, inp); ksr = so->so_rcv.sb_tls_info; - if (ktls_session_genvis(ksr, xig.xig_gen)) { + if (ksr != NULL) { + ksr->gen = xig.xig_gen; p = true; if (ek) { sz = SIZE_T_MAX; @@ -2726,7 +2733,8 @@ } } kss = so->so_snd.sb_tls_info; - if (ktls_session_genvis(kss, xig.xig_gen)) { + if (kss != NULL) { + kss->gen = xig.xig_gen; p = true; if (ek) { sz = SIZE_T_MAX; @@ -2783,11 +2791,11 @@ ksr = so->so_rcv.sb_tls_info; kss = so->so_snd.sb_tls_info; xktls = (struct xktls_session *)buf; - if (ktls_session_genvis(ksr, xig.xig_gen)) { + if (ksr != NULL && ksr->gen == xig.xig_gen) { p = true; ktls_session_to_xktls_onedir(ksr, ek, &xktls->rcv); } - if (ktls_session_genvis(kss, xig.xig_gen)) { + if (kss != NULL && kss->gen == xig.xig_gen) { p = true; ktls_session_to_xktls_onedir(kss, ek, &xktls->snd); } @@ -2798,7 +2806,7 @@ xktls->so_pcb = (kvaddr_t)inp; memcpy(&xktls->coninf, &inp->inp_inc, sizeof(xktls->coninf)); len = sizeof(*xktls); - if (ktls_session_genvis(ksr, xig.xig_gen)) { + if (ksr != NULL && ksr->gen == xig.xig_gen) { if (ek) { sz = buflen - len; ktls_session_copy_keys(ksr, buf + len, &sz); @@ -2815,7 +2823,7 @@ len += sz; } } - if (ktls_session_genvis(kss, xig.xig_gen)) { + if (kss != NULL && kss->gen == xig.xig_gen) { if (ek) { sz = buflen - len; ktls_session_copy_keys(kss, buf + len, &sz); @@ -2845,8 +2853,6 @@ } if (error == 0) { - atomic_thread_fence_rel(); - xig.xig_gen = atomic_load_64(&ktls_glob_gen); xig.xig_sogen = so_gencnt; xig.xig_count = cnt; error = SYSCTL_OUT(req, &xig, sizeof(xig)); @@ -2856,16 +2862,27 @@ return (error); } +static int +tcp_ktlslist1(SYSCTL_HANDLER_ARGS, bool export_keys) +{ + int res; + + sx_xlock(&ktlslist_lock); + res = tcp_ktlslist_locked(oidp, arg1, arg2, req, export_keys); + sx_xunlock(&ktlslist_lock); + return (res); +} + static int tcp_ktlslist_nokeys(SYSCTL_HANDLER_ARGS) { - return (tcp_ktlslist(oidp, arg1, arg2, req, false)); + return (tcp_ktlslist1(oidp, arg1, arg2, req, false)); } static int tcp_ktlslist_wkeys(SYSCTL_HANDLER_ARGS) { - return (tcp_ktlslist(oidp, arg1, arg2, req, true)); + return (tcp_ktlslist1(oidp, arg1, arg2, req, true)); } SYSCTL_PROC(_net_inet_tcp, TCPCTL_KTLSLIST, ktlslist, diff --git a/sys/sys/ktls.h b/sys/sys/ktls.h --- a/sys/sys/ktls.h +++ b/sys/sys/ktls.h @@ -233,7 +233,6 @@ } __aligned(CACHE_LINE_SIZE); extern unsigned int ktls_ifnet_max_rexmit_pct; -extern uint64_t ktls_glob_gen; typedef enum { KTLS_MBUF_CRYPTO_ST_MIXED = 0, @@ -283,12 +282,6 @@ ktls_destroy(tls); } -static inline bool -ktls_session_genvis(const struct ktls_session *ks, uint64_t gen) -{ - return (ks != NULL && ks->gen <= gen); -} - void ktls_session_to_xktls_onedir(const struct ktls_session *ks, bool export_keys, struct xktls_session_onedir *xktls_od); void ktls_session_copy_keys(const struct ktls_session *ktls,