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 373511338d 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.

MFC after:	2 weeks
This commit is contained in:
Rick Macklem 2022-05-15 11:51:56 -07:00
parent 390c9ea029
commit 0b4f2ab0e9
2 changed files with 15 additions and 18 deletions

View file

@ -944,7 +944,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;
@ -992,13 +992,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) {
@ -1023,8 +1020,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.
@ -1051,10 +1048,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);

View file

@ -804,8 +804,8 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_msg *msg,
}
/*
* 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.
@ -863,10 +863,10 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_msg *msg,
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);