Add the MSG_TLSAPPDATA flag to indicate "return ENXIO" for non-application TLS

data records.

The kernel RPC cannot process non-application data records when
using TLS. It must to an upcall to a userspace daemon that will
call SSL_read() to process them.

This patch adds a new flag called MSG_TLSAPPDATA that the kernel
RPC can use to tell sorecieve() to return ENXIO instead of a non-application
data record, when that is what is at the top of the receive queue.
I put the code in #ifdef KERN_TLS/#endif, although it will build without
that, so that it is recognized as only useful when KERN_TLS is enabled.
The alternative to doing this is to have the kernel RPC re-queue the
non-application data message after receiving it, but that seems more
complicated and might introduce message ordering issues when there
are multiple non-application data records one after another.

I do not know what, if any, changes will be required to support TLS1.3.

Reviewed by:	glebius
Differential Revision:	https://reviews.freebsd.org/D25923
This commit is contained in:
Rick Macklem 2020-08-19 23:42:33 +00:00
parent 5949d13fab
commit 102829aa92
2 changed files with 27 additions and 0 deletions

View File

@ -2056,6 +2056,32 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio,
if (m != NULL && m->m_type == MT_CONTROL) {
struct mbuf *cm = NULL, *cmn;
struct mbuf **cme = &cm;
#ifdef KERN_TLS
struct cmsghdr *cmsg;
struct tls_get_record tgr;
/*
* For MSG_TLSAPPDATA, check for a non-application data
* record. If found, return ENXIO without removing
* it from the receive queue. This allows a subsequent
* call without MSG_TLSAPPDATA to receive it.
* Note that, for TLS, there should only be a single
* control mbuf with the TLS_GET_RECORD message in it.
*/
if (flags & MSG_TLSAPPDATA) {
cmsg = mtod(m, struct cmsghdr *);
if (cmsg->cmsg_type == TLS_GET_RECORD &&
cmsg->cmsg_len == CMSG_LEN(sizeof(tgr))) {
memcpy(&tgr, CMSG_DATA(cmsg), sizeof(tgr));
/* This will need to change for TLS 1.3. */
if (tgr.tls_type != TLS_RLTYPE_APP) {
SOCKBUF_UNLOCK(&so->so_rcv);
error = ENXIO;
goto release;
}
}
}
#endif
do {
if (flags & MSG_PEEK) {

View File

@ -468,6 +468,7 @@ struct msghdr {
#endif
#ifdef _KERNEL
#define MSG_MORETOCOME 0x00100000 /* additional data pending */
#define MSG_TLSAPPDATA 0x00200000 /* only soreceive() app. data (TLS) */
#endif
/*