Commit 2837966a authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Keith Busch
Browse files

nvme-tcp: control message handling for recvmsg()



kTLS is sending TLS ALERT messages as control messages for recvmsg().
As we can't do anything sensible with it just abort the connection
and let the userspace agent to a re-negotiation.

Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent be8e82ca
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <net/sock.h>
#include <net/tcp.h>
#include <net/tls.h>
#include <net/tls_prot.h>
#include <net/handshake.h>
#include <linux/blk-mq.h>
#include <crypto/hash.h>
@@ -1369,6 +1370,8 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
{
	struct nvme_tcp_icreq_pdu *icreq;
	struct nvme_tcp_icresp_pdu *icresp;
	char cbuf[CMSG_LEN(sizeof(char))] = {};
	u8 ctype;
	struct msghdr msg = {};
	struct kvec iov;
	bool ctrl_hdgst, ctrl_ddgst;
@@ -1406,11 +1409,23 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
	memset(&msg, 0, sizeof(msg));
	iov.iov_base = icresp;
	iov.iov_len = sizeof(*icresp);
	if (queue->ctrl->ctrl.opts->tls) {
		msg.msg_control = cbuf;
		msg.msg_controllen = sizeof(cbuf);
	}
	ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
			iov.iov_len, msg.msg_flags);
	if (ret < 0)
		goto free_icresp;

	if (queue->ctrl->ctrl.opts->tls) {
		ctype = tls_get_record_type(queue->sock->sk,
					    (struct cmsghdr *)cbuf);
		if (ctype != TLS_RECORD_TYPE_DATA) {
			pr_err("queue %d: unhandled TLS record %d\n",
			       nvme_tcp_queue_id(queue), ctype);
			return -ENOTCONN;
		}
	}
	ret = -EINVAL;
	if (icresp->hdr.type != nvme_tcp_icresp) {
		pr_err("queue %d: bad type returned %d\n",