git: 8908c590e365 - stable/13 - krpc: Fix NFS-over-TLS for KTLS1.3
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 31 May 2022 00:40:02 UTC
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=8908c590e365584666532d59125fffd721b267d3 commit 8908c590e365584666532d59125fffd721b267d3 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2022-05-15 18:51:56 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2022-05-31 00:38:43 +0000 krpc: Fix NFS-over-TLS for KTLS1.3 When NFS-over-TLS uses KTLS1.3, the client can receive post-handshake handshake records. These records can be safely thown away, but are not handled correctly via the rpctls_ct_handlerecord() upcall to the daemon. Commit 373511338d95 changed soreceive_generic() so that it will only return ENXIO for Alert records when MSG_TLSAPPDATA is specified. As such, the post-handshake handshake records will be returned to the krpc. This patch modifies the krpc so that it will throw these records away, which seems sufficient to make NFS-over-TLS work with KTLS1.3. This change has no effect on the use of KTLS1.2, since it does not generate post-handshake handshake records. (cherry picked from commit 0b4f2ab0e91307bd1fa6e884b0fccef9d10d5a2d) --- sys/rpc/clnt_vc.c | 21 +++++++++------------ sys/rpc/svc_vc.c | 12 ++++++------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c index 7d22c670b017..8ad6746eb485 100644 --- a/sys/rpc/clnt_vc.c +++ b/sys/rpc/clnt_vc.c @@ -946,7 +946,7 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag) { struct ct_data *ct = (struct ct_data *) arg; struct uio uio; - struct mbuf *m, *m2, **ctrlp; + struct mbuf *m, *m2; struct ct_request *cr; int error, rcvflag, foundreq; uint32_t xid_plus_direction[2], header; @@ -994,13 +994,10 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag) m2 = m = NULL; rcvflag = MSG_DONTWAIT | MSG_SOCALLBCK; if (ct->ct_sslrefno != 0 && (ct->ct_rcvstate & - RPCRCVSTATE_NORMAL) != 0) { + RPCRCVSTATE_NORMAL) != 0) rcvflag |= MSG_TLSAPPDATA; - ctrlp = NULL; - } else - ctrlp = &m2; SOCKBUF_UNLOCK(&so->so_rcv); - error = soreceive(so, NULL, &uio, &m, ctrlp, &rcvflag); + error = soreceive(so, NULL, &uio, &m, &m2, &rcvflag); SOCKBUF_LOCK(&so->so_rcv); if (error == EWOULDBLOCK) { @@ -1025,8 +1022,8 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag) } /* - * A return of ENXIO indicates that there is a - * non-application data record at the head of the + * A return of ENXIO indicates that there is an + * alert record at the head of the * socket's receive queue, for TLS connections. * This record needs to be handled in userland * via an SSL_read() call, so do an upcall to the daemon. @@ -1053,10 +1050,10 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag) cmsg->cmsg_len == CMSG_LEN(sizeof(tgr))) { memcpy(&tgr, CMSG_DATA(cmsg), sizeof(tgr)); /* - * This should have been handled by - * setting RPCRCVSTATE_UPCALLNEEDED in - * ct_rcvstate but if not, all we can do - * is toss it away. + * TLS_RLTYPE_ALERT records should be handled + * since soreceive() would have returned + * ENXIO. Just throw any other + * non-TLS_RLTYPE_APP records away. */ if (tgr.tls_type != TLS_RLTYPE_APP) { m_freem(m); diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index 77452d906594..eb63cb1da4e4 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -806,8 +806,8 @@ tryagain: } /* - * A return of ENXIO indicates that there is a - * non-application data record at the head of the + * A return of ENXIO indicates that there is an + * alert record at the head of the * socket's receive queue, for TLS connections. * This record needs to be handled in userland * via an SSL_read() call, so do an upcall to the daemon. @@ -865,10 +865,10 @@ tryagain: cmsg->cmsg_len == CMSG_LEN(sizeof(tgr))) { memcpy(&tgr, CMSG_DATA(cmsg), sizeof(tgr)); /* - * This should have been handled by - * the rpctls_svc_handlerecord() - * upcall. If not, all we can do is - * toss it away. + * TLS_RLTYPE_ALERT records should be handled + * since soreceive() would have returned + * ENXIO. Just throw any other + * non-TLS_RLTYPE_APP records away. */ if (tgr.tls_type != TLS_RLTYPE_APP) { m_freem(m);