Commit 39067dda authored by Chuck Lever's avatar Chuck Lever Committed by Jakub Kicinski

SUNRPC: Use new helpers to handle TLS Alerts

Use the helpers to parse the level and description fields in
incoming alerts. "Warning" alerts are discarded, and "fatal"
alerts mean the session is no longer valid.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Link: https://lore.kernel.org/r/169047944747.5241.1974889594004407123.stgit@oracle-102.nfsv4bat.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 39d0e38d
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#include <net/udp.h> #include <net/udp.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/tcp_states.h> #include <net/tcp_states.h>
#include <net/tls.h>
#include <net/tls_prot.h> #include <net/tls_prot.h>
#include <net/handshake.h> #include <net/handshake.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -227,14 +226,15 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining) ...@@ -227,14 +226,15 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
} }
static int static int
svc_tcp_sock_process_cmsg(struct svc_sock *svsk, struct msghdr *msg, svc_tcp_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
struct cmsghdr *cmsg, int ret) struct cmsghdr *cmsg, int ret)
{ {
if (cmsg->cmsg_level == SOL_TLS && u8 content_type = tls_get_record_type(sock->sk, cmsg);
cmsg->cmsg_type == TLS_GET_RECORD_TYPE) { u8 level, description;
u8 content_type = *((u8 *)CMSG_DATA(cmsg));
switch (content_type) { switch (content_type) {
case 0:
break;
case TLS_RECORD_TYPE_DATA: case TLS_RECORD_TYPE_DATA:
/* TLS sets EOR at the end of each application data /* TLS sets EOR at the end of each application data
* record, even though there might be more frames * record, even though there might be more frames
...@@ -243,12 +243,14 @@ svc_tcp_sock_process_cmsg(struct svc_sock *svsk, struct msghdr *msg, ...@@ -243,12 +243,14 @@ svc_tcp_sock_process_cmsg(struct svc_sock *svsk, struct msghdr *msg,
msg->msg_flags &= ~MSG_EOR; msg->msg_flags &= ~MSG_EOR;
break; break;
case TLS_RECORD_TYPE_ALERT: case TLS_RECORD_TYPE_ALERT:
ret = -ENOTCONN; tls_alert_recv(sock->sk, msg, &level, &description);
ret = (level == TLS_ALERT_LEVEL_FATAL) ?
-ENOTCONN : -EAGAIN;
break; break;
default: default:
/* discard this record type */
ret = -EAGAIN; ret = -EAGAIN;
} }
}
return ret; return ret;
} }
...@@ -259,13 +261,14 @@ svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg) ...@@ -259,13 +261,14 @@ svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg)
struct cmsghdr cmsg; struct cmsghdr cmsg;
u8 buf[CMSG_SPACE(sizeof(u8))]; u8 buf[CMSG_SPACE(sizeof(u8))];
} u; } u;
struct socket *sock = svsk->sk_sock;
int ret; int ret;
msg->msg_control = &u; msg->msg_control = &u;
msg->msg_controllen = sizeof(u); msg->msg_controllen = sizeof(u);
ret = sock_recvmsg(svsk->sk_sock, msg, MSG_DONTWAIT); ret = sock_recvmsg(sock, msg, MSG_DONTWAIT);
if (unlikely(msg->msg_controllen != sizeof(u))) if (unlikely(msg->msg_controllen != sizeof(u)))
ret = svc_tcp_sock_process_cmsg(svsk, msg, &u.cmsg, ret); ret = svc_tcp_sock_process_cmsg(sock, msg, &u.cmsg, ret);
return ret; return ret;
} }
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include <net/checksum.h> #include <net/checksum.h>
#include <net/udp.h> #include <net/udp.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/tls.h>
#include <net/tls_prot.h> #include <net/tls_prot.h>
#include <net/handshake.h> #include <net/handshake.h>
...@@ -361,11 +360,12 @@ static int ...@@ -361,11 +360,12 @@ static int
xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg, xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
struct cmsghdr *cmsg, int ret) struct cmsghdr *cmsg, int ret)
{ {
if (cmsg->cmsg_level == SOL_TLS && u8 content_type = tls_get_record_type(sock->sk, cmsg);
cmsg->cmsg_type == TLS_GET_RECORD_TYPE) { u8 level, description;
u8 content_type = *((u8 *)CMSG_DATA(cmsg));
switch (content_type) { switch (content_type) {
case 0:
break;
case TLS_RECORD_TYPE_DATA: case TLS_RECORD_TYPE_DATA:
/* TLS sets EOR at the end of each application data /* TLS sets EOR at the end of each application data
* record, even though there might be more frames * record, even though there might be more frames
...@@ -374,12 +374,14 @@ xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg, ...@@ -374,12 +374,14 @@ xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
msg->msg_flags &= ~MSG_EOR; msg->msg_flags &= ~MSG_EOR;
break; break;
case TLS_RECORD_TYPE_ALERT: case TLS_RECORD_TYPE_ALERT:
ret = -ENOTCONN; tls_alert_recv(sock->sk, msg, &level, &description);
ret = (level == TLS_ALERT_LEVEL_FATAL) ?
-EACCES : -EAGAIN;
break; break;
default: default:
/* discard this record type */
ret = -EAGAIN; ret = -EAGAIN;
} }
}
return ret; return ret;
} }
...@@ -778,6 +780,8 @@ static void xs_stream_data_receive(struct sock_xprt *transport) ...@@ -778,6 +780,8 @@ static void xs_stream_data_receive(struct sock_xprt *transport)
} }
if (ret == -ESHUTDOWN) if (ret == -ESHUTDOWN)
kernel_sock_shutdown(transport->sock, SHUT_RDWR); kernel_sock_shutdown(transport->sock, SHUT_RDWR);
else if (ret == -EACCES)
xprt_wake_pending_tasks(&transport->xprt, -EACCES);
else else
xs_poll_check_readable(transport); xs_poll_check_readable(transport);
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment