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: 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>
This commit is contained in:
parent
39d0e38dcc
commit
39067dda1d
@ -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));
|
||||
u8 content_type = tls_get_record_type(sock->sk, cmsg);
|
||||
u8 level, description;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
u8 content_type = tls_get_record_type(sock->sk, cmsg);
|
||||
u8 level, description;
|
||||
|
||||
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;
|
||||
}
|
||||
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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user