Date: Sat, 11 Jul 2020 03:39:44 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r363089 - in projects/nfs-over-tls/sys/rpc: . rpcsec_tls Message-ID: <202007110339.06B3digg086633@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sat Jul 11 03:39:44 2020 New Revision: 363089 URL: https://svnweb.freebsd.org/changeset/base/363089 Log: Close a could of windows where, if the TLS upcall daemon terminated, the socket would not be closed properly. This patch closes these windows by setting the flag that indicates that a handshake is in progress just when the socket is associated with a file descriptor for the daemon. Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/clnt_rc.c Fri Jul 10 22:59:26 2020 (r363088) +++ projects/nfs-over-tls/sys/rpc/clnt_rc.c Sat Jul 11 03:39:44 2020 (r363089) @@ -198,16 +198,6 @@ clnt_reconnect_connect(CLIENT *cl) (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers, rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr); if (rc->rc_tls && newclient != NULL) { - /* - * Set ssl refno so that clnt_vc_destroy() will not - * close the socket and will leave that for the - * daemon to do. It is possible that the upcall - * will time out, so that closing the socket via - * the CLNT_CLOSE() below would happen too soon. - */ - ssl[0] = ssl[1] = 0; - ssl[2] = RPCTLS_REFNO_HANDSHAKE; - CLNT_CONTROL(newclient, CLSET_TLS, ssl); printf("at rpctls_connect\n"); stat = rpctls_connect(newclient, so, ssl, &reterr); printf("aft rpctls_connect=%d ssl=%jd\n", stat, (uintmax_t)ssl[2]); Modified: projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c Fri Jul 10 22:59:26 2020 (r363088) +++ projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c Sat Jul 11 03:39:44 2020 (r363089) @@ -75,14 +75,16 @@ static struct syscall_helper_data rpctls_syscalls[] = static CLIENT *rpctls_connect_handle; static struct mtx rpctls_connect_lock; static struct socket *rpctls_connect_so = NULL; +static CLIENT *rpctls_connect_cl = NULL; static CLIENT *rpctls_server_handle; static struct mtx rpctls_server_lock; static struct socket *rpctls_server_so = NULL; +static SVCXPRT *rpctls_server_xprt = NULL; static struct opaque_auth rpctls_null_verf; static CLIENT *rpctls_connect_client(void); static CLIENT *rpctls_server_client(void); -static enum clnt_stat rpctls_server(struct socket *so, +static enum clnt_stat rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp, uid_t *uid, int *ngrps, gid_t **gids); @@ -113,9 +115,11 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_sy struct netconfig *nconf; struct file *fp; struct socket *so; + SVCXPRT *xprt; char path[MAXPATHLEN]; int fd = -1, error, try_count; - CLIENT *cl, *oldcl; + CLIENT *cl, *oldcl, *concl; + uint64_t ssl[3]; struct timeval timeo; #ifdef KERN_TLS u_int maxlen; @@ -272,11 +276,21 @@ printf("In connect\n"); mtx_lock(&rpctls_connect_lock); so = rpctls_connect_so; rpctls_connect_so = NULL; + concl = rpctls_connect_cl; + rpctls_connect_cl = NULL; mtx_unlock(&rpctls_connect_lock); if (so != NULL) { error = falloc(td, &fp, &fd, 0); printf("falloc=%d fd=%d\n", error, fd); if (error == 0) { + /* + * Set ssl refno so that clnt_vc_destroy() will + * not close the socket and will leave that for + * the daemon to do. + */ + ssl[0] = ssl[1] = 0; + ssl[2] = RPCTLS_REFNO_HANDSHAKE; + CLNT_CONTROL(concl, CLSET_TLS, ssl); finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops); fdrop(fp, td); /* Drop fp reference. */ @@ -291,11 +305,21 @@ printf("In srvconnect\n"); mtx_lock(&rpctls_server_lock); so = rpctls_server_so; rpctls_server_so = NULL; + xprt = rpctls_server_xprt; + rpctls_server_xprt = NULL; mtx_unlock(&rpctls_server_lock); if (so != NULL) { error = falloc(td, &fp, &fd, 0); printf("falloc=%d fd=%d\n", error, fd); if (error == 0) { + /* + * Once this file descriptor is associated + * with the socket, it cannot be closed by + * the server side krpc code (svc_vc.c). + */ + sx_xlock(&xprt->xp_lock); + xprt->xp_tls = RPCTLS_FLAGS_HANDSHFAIL; + sx_xunlock(&xprt->xp_lock); finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops); fdrop(fp, td); /* Drop fp reference. */ @@ -387,6 +411,7 @@ printf("aft NULLRPC=%d\n", stat); "rtlscn", 0); rpctls_connect_busy = true; rpctls_connect_so = so; + rpctls_connect_cl = newclient; mtx_unlock(&rpctls_connect_lock); printf("rpctls_conect so=%p\n", so); @@ -423,6 +448,7 @@ printf("did soshutdown rd\n"); /* Once the upcall is done, the daemon is done with the fp and so. */ mtx_lock(&rpctls_connect_lock); rpctls_connect_so = NULL; + rpctls_connect_cl = NULL; rpctls_connect_busy = false; wakeup(&rpctls_connect_busy); mtx_unlock(&rpctls_connect_lock); @@ -551,7 +577,7 @@ printf("aft srv disconnect upcall=%d\n", stat); /* Do an upcall for a new server socket using TLS. */ static enum clnt_stat -rpctls_server(struct socket *so, uint32_t *flags, uint64_t *sslp, +rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp, uid_t *uid, int *ngrps, gid_t **gids) { enum clnt_stat stat; @@ -575,6 +601,7 @@ printf("server_client=%p\n", cl); "rtlssn", 0); rpctls_server_busy = true; rpctls_server_so = so; + rpctls_server_xprt = xprt; mtx_unlock(&rpctls_server_lock); printf("rpctls_conect so=%p\n", so); @@ -611,6 +638,7 @@ printf("aft server upcall stat=%d flags=0x%x\n", stat, /* Once the upcall is done, the daemon is done with the fp and so. */ mtx_lock(&rpctls_server_lock); rpctls_server_so = NULL; + rpctls_server_xprt = NULL; rpctls_server_busy = false; wakeup(&rpctls_server_busy); mtx_unlock(&rpctls_server_lock); @@ -686,7 +714,7 @@ printf("authtls: null reply=%d\n", call_stat); } /* Do an upcall to do the TLS handshake. */ - stat = rpctls_server(rqst->rq_xprt->xp_socket, &flags, + stat = rpctls_server(xprt, xprt->xp_socket, &flags, ssl, &uid, &ngrps, &gidp); /* Re-enable reception on the socket within the krpc. */ @@ -704,9 +732,6 @@ printf("authtls: null reply=%d\n", call_stat); xprt->xp_gidp = gidp; printf("got uid=%d ngrps=%d gidp=%p\n", uid, ngrps, gidp); } - } else { - /* Mark that TLS handshake failed. */ - xprt->xp_tls = RPCTLS_FLAGS_HANDSHFAIL; } sx_xunlock(&xprt->xp_lock); xprt_active(xprt); /* Harmless if already active. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007110339.06B3digg086633>