mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 06:33:34 +00:00
SUNRPC: Capture CMSG metadata on client-side receive
kTLS sockets use CMSG to report decryption errors and the need for session re-keying. For RPC-with-TLS, an "application data" message contains a ULP payload, and that is passed along to the RPC client. An "alert" message triggers connection reset. Everything else is discarded. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
0d3ca07ffd
commit
dea034b963
@ -47,6 +47,8 @@
|
||||
#include <net/checksum.h>
|
||||
#include <net/udp.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/tls.h>
|
||||
|
||||
#include <linux/bvec.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/uio.h>
|
||||
@ -347,13 +349,56 @@ xs_alloc_sparse_pages(struct xdr_buf *buf, size_t want, gfp_t gfp)
|
||||
return want;
|
||||
}
|
||||
|
||||
static int
|
||||
xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
|
||||
struct cmsghdr *cmsg, int ret)
|
||||
{
|
||||
if (cmsg->cmsg_level == SOL_TLS &&
|
||||
cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
|
||||
u8 content_type = *((u8 *)CMSG_DATA(cmsg));
|
||||
|
||||
switch (content_type) {
|
||||
case TLS_RECORD_TYPE_DATA:
|
||||
/* TLS sets EOR at the end of each application data
|
||||
* record, even though there might be more frames
|
||||
* waiting to be decrypted.
|
||||
*/
|
||||
msg->msg_flags &= ~MSG_EOR;
|
||||
break;
|
||||
case TLS_RECORD_TYPE_ALERT:
|
||||
ret = -ENOTCONN;
|
||||
break;
|
||||
default:
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
xs_sock_recv_cmsg(struct socket *sock, struct msghdr *msg, int flags)
|
||||
{
|
||||
union {
|
||||
struct cmsghdr cmsg;
|
||||
u8 buf[CMSG_SPACE(sizeof(u8))];
|
||||
} u;
|
||||
int ret;
|
||||
|
||||
msg->msg_control = &u;
|
||||
msg->msg_controllen = sizeof(u);
|
||||
ret = sock_recvmsg(sock, msg, flags);
|
||||
if (msg->msg_controllen != sizeof(u))
|
||||
ret = xs_sock_process_cmsg(sock, msg, &u.cmsg, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
xs_sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags, size_t seek)
|
||||
{
|
||||
ssize_t ret;
|
||||
if (seek != 0)
|
||||
iov_iter_advance(&msg->msg_iter, seek);
|
||||
ret = sock_recvmsg(sock, msg, flags);
|
||||
ret = xs_sock_recv_cmsg(sock, msg, flags);
|
||||
return ret > 0 ? ret + seek : ret;
|
||||
}
|
||||
|
||||
@ -379,7 +424,7 @@ xs_read_discard(struct socket *sock, struct msghdr *msg, int flags,
|
||||
size_t count)
|
||||
{
|
||||
iov_iter_discard(&msg->msg_iter, ITER_DEST, count);
|
||||
return sock_recvmsg(sock, msg, flags);
|
||||
return xs_sock_recv_cmsg(sock, msg, flags);
|
||||
}
|
||||
|
||||
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
|
||||
|
Loading…
Reference in New Issue
Block a user