SUNRPC: Use new helpers to handle TLS Alerts
authorChuck Lever <chuck.lever@oracle.com>
Thu, 27 Jul 2023 17:37:37 +0000 (13:37 -0400)
committerJakub Kicinski <kuba@kernel.org>
Fri, 28 Jul 2023 21:07:59 +0000 (14:07 -0700)
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: Chuck Lever <chuck.lever@oracle.com>
Link: https://lore.kernel.org/r/169047944747.5241.1974889594004407123.stgit@oracle-102.nfsv4bat.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/sunrpc/svcsock.c
net/sunrpc/xprtsock.c

index cca6ee7..2ed29e4 100644 (file)
@@ -43,7 +43,6 @@
 #include <net/udp.h>
 #include <net/tcp.h>
 #include <net/tcp_states.h>
-#include <net/tls.h>
 #include <net/tls_prot.h>
 #include <net/handshake.h>
 #include <linux/uaccess.h>
@@ -227,27 +226,30 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
 }
 
 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)
 {
-       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;
-               }
+       u8 content_type = tls_get_record_type(sock->sk, cmsg);
+       u8 level, description;
+
+       switch (content_type) {
+       case 0:
+               break;
+       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:
+               tls_alert_recv(sock->sk, msg, &level, &description);
+               ret = (level == TLS_ALERT_LEVEL_FATAL) ?
+                       -ENOTCONN : -EAGAIN;
+               break;
+       default:
+               /* discard this record type */
+               ret = -EAGAIN;
        }
        return ret;
 }
@@ -259,13 +261,14 @@ svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg)
                struct cmsghdr  cmsg;
                u8              buf[CMSG_SPACE(sizeof(u8))];
        } u;
+       struct socket *sock = svsk->sk_sock;
        int ret;
 
        msg->msg_control = &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)))
-               ret = svc_tcp_sock_process_cmsg(svsk, msg, &u.cmsg, ret);
+               ret = svc_tcp_sock_process_cmsg(sock, msg, &u.cmsg, ret);
        return ret;
 }
 
index 5096aa6..268a2cc 100644 (file)
@@ -47,7 +47,6 @@
 #include <net/checksum.h>
 #include <net/udp.h>
 #include <net/tcp.h>
-#include <net/tls.h>
 #include <net/tls_prot.h>
 #include <net/handshake.h>
 
@@ -361,24 +360,27 @@ 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;
-               }
+       u8 content_type = tls_get_record_type(sock->sk, cmsg);
+       u8 level, description;
+
+       switch (content_type) {
+       case 0:
+               break;
+       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:
+               tls_alert_recv(sock->sk, msg, &level, &description);
+               ret = (level == TLS_ALERT_LEVEL_FATAL) ?
+                       -EACCES : -EAGAIN;
+               break;
+       default:
+               /* discard this record type */
+               ret = -EAGAIN;
        }
        return ret;
 }
@@ -778,6 +780,8 @@ static void xs_stream_data_receive(struct sock_xprt *transport)
        }
        if (ret == -ESHUTDOWN)
                kernel_sock_shutdown(transport->sock, SHUT_RDWR);
+       else if (ret == -EACCES)
+               xprt_wake_pending_tasks(&transport->xprt, -EACCES);
        else
                xs_poll_check_readable(transport);
 out: