Skip to content

Commit 39067dd

Browse files
chuckleverkuba-moo
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/169047944747.5241.1974889594004407123.stgit@oracle-102.nfsv4bat.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 39d0e38 commit 39067dd

File tree

2 files changed

+48
-41
lines changed

2 files changed

+48
-41
lines changed

net/sunrpc/svcsock.c

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
#include <net/udp.h>
4444
#include <net/tcp.h>
4545
#include <net/tcp_states.h>
46-
#include <net/tls.h>
4746
#include <net/tls_prot.h>
4847
#include <net/handshake.h>
4948
#include <linux/uaccess.h>
@@ -227,27 +226,30 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
227226
}
228227

229228
static int
230-
svc_tcp_sock_process_cmsg(struct svc_sock *svsk, struct msghdr *msg,
229+
svc_tcp_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
231230
struct cmsghdr *cmsg, int ret)
232231
{
233-
if (cmsg->cmsg_level == SOL_TLS &&
234-
cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
235-
u8 content_type = *((u8 *)CMSG_DATA(cmsg));
236-
237-
switch (content_type) {
238-
case TLS_RECORD_TYPE_DATA:
239-
/* TLS sets EOR at the end of each application data
240-
* record, even though there might be more frames
241-
* waiting to be decrypted.
242-
*/
243-
msg->msg_flags &= ~MSG_EOR;
244-
break;
245-
case TLS_RECORD_TYPE_ALERT:
246-
ret = -ENOTCONN;
247-
break;
248-
default:
249-
ret = -EAGAIN;
250-
}
232+
u8 content_type = tls_get_record_type(sock->sk, cmsg);
233+
u8 level, description;
234+
235+
switch (content_type) {
236+
case 0:
237+
break;
238+
case TLS_RECORD_TYPE_DATA:
239+
/* TLS sets EOR at the end of each application data
240+
* record, even though there might be more frames
241+
* waiting to be decrypted.
242+
*/
243+
msg->msg_flags &= ~MSG_EOR;
244+
break;
245+
case TLS_RECORD_TYPE_ALERT:
246+
tls_alert_recv(sock->sk, msg, &level, &description);
247+
ret = (level == TLS_ALERT_LEVEL_FATAL) ?
248+
-ENOTCONN : -EAGAIN;
249+
break;
250+
default:
251+
/* discard this record type */
252+
ret = -EAGAIN;
251253
}
252254
return ret;
253255
}
@@ -259,13 +261,14 @@ svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg)
259261
struct cmsghdr cmsg;
260262
u8 buf[CMSG_SPACE(sizeof(u8))];
261263
} u;
264+
struct socket *sock = svsk->sk_sock;
262265
int ret;
263266

264267
msg->msg_control = &u;
265268
msg->msg_controllen = sizeof(u);
266-
ret = sock_recvmsg(svsk->sk_sock, msg, MSG_DONTWAIT);
269+
ret = sock_recvmsg(sock, msg, MSG_DONTWAIT);
267270
if (unlikely(msg->msg_controllen != sizeof(u)))
268-
ret = svc_tcp_sock_process_cmsg(svsk, msg, &u.cmsg, ret);
271+
ret = svc_tcp_sock_process_cmsg(sock, msg, &u.cmsg, ret);
269272
return ret;
270273
}
271274

net/sunrpc/xprtsock.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#include <net/checksum.h>
4848
#include <net/udp.h>
4949
#include <net/tcp.h>
50-
#include <net/tls.h>
5150
#include <net/tls_prot.h>
5251
#include <net/handshake.h>
5352

@@ -361,24 +360,27 @@ static int
361360
xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
362361
struct cmsghdr *cmsg, int ret)
363362
{
364-
if (cmsg->cmsg_level == SOL_TLS &&
365-
cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
366-
u8 content_type = *((u8 *)CMSG_DATA(cmsg));
367-
368-
switch (content_type) {
369-
case TLS_RECORD_TYPE_DATA:
370-
/* TLS sets EOR at the end of each application data
371-
* record, even though there might be more frames
372-
* waiting to be decrypted.
373-
*/
374-
msg->msg_flags &= ~MSG_EOR;
375-
break;
376-
case TLS_RECORD_TYPE_ALERT:
377-
ret = -ENOTCONN;
378-
break;
379-
default:
380-
ret = -EAGAIN;
381-
}
363+
u8 content_type = tls_get_record_type(sock->sk, cmsg);
364+
u8 level, description;
365+
366+
switch (content_type) {
367+
case 0:
368+
break;
369+
case TLS_RECORD_TYPE_DATA:
370+
/* TLS sets EOR at the end of each application data
371+
* record, even though there might be more frames
372+
* waiting to be decrypted.
373+
*/
374+
msg->msg_flags &= ~MSG_EOR;
375+
break;
376+
case TLS_RECORD_TYPE_ALERT:
377+
tls_alert_recv(sock->sk, msg, &level, &description);
378+
ret = (level == TLS_ALERT_LEVEL_FATAL) ?
379+
-EACCES : -EAGAIN;
380+
break;
381+
default:
382+
/* discard this record type */
383+
ret = -EAGAIN;
382384
}
383385
return ret;
384386
}
@@ -778,6 +780,8 @@ static void xs_stream_data_receive(struct sock_xprt *transport)
778780
}
779781
if (ret == -ESHUTDOWN)
780782
kernel_sock_shutdown(transport->sock, SHUT_RDWR);
783+
else if (ret == -EACCES)
784+
xprt_wake_pending_tasks(&transport->xprt, -EACCES);
781785
else
782786
xs_poll_check_readable(transport);
783787
out:

0 commit comments

Comments
 (0)