[PATCH 1/2] nvme-tcp: move the TLS record read loop into a helper
sashiko-bot at kernel.org
sashiko-bot at kernel.org
Mon Nov 9 11:11:26 PST 2026
Thank you for your contribution! Sashiko AI review found no new issues
in this patch, but noticed 1 related pre-existing issue it does not
introduce:
- [Medium] nvme-tcp: unaligned cmsghdr access in
nvme_tcp_init_connection() [1]
--
commit b550db6841afde16fa08cb67f259ffa9462cfbdb
Author: Martin Belanger <martin.belanger at dell.com>
nvme-tcp: move the TLS record read loop into a helper
This commit extracts the TLS record draining loop from
nvme_tcp_skip_tls_record() into a new nvme_tcp_drain_tls_record() helper.
> diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
> index 7ecc6c007f8d4..bf71e6f6a6ef6 100644
> --- a/drivers/nvme/host/tcp.c
> +++ b/drivers/nvme/host/tcp.c
> @@ -1623,31 +1623,16 @@ static int nvme_tcp_recv_tls_alert(struct nvme_tcp_queue *queue,
> }
>
> /*
> - * Discard a TLS record that arrived in place of the ICResp. A peer may send
> - * a NewSessionTicket as soon as the handshake completes.
> + * Read the rest of a TLS record whose first part was read into @msg.
> *
> - * Returns 0 when the record was discarded and the ICResp can be read, or a
> - * negative errno if the connection cannot continue.
> + * Returns the bytes read, or a negative errno.
> */
> -static int nvme_tcp_skip_tls_record(struct nvme_tcp_queue *queue,
> - struct msghdr *msg, u8 ctype, int len)
> +static int nvme_tcp_drain_tls_record(struct nvme_tcp_queue *queue,
> + struct msghdr *msg, int flags)
> {
> u8 buf[NVME_TCP_TLS_REC_CHUNK];
> - int ret;
> + int ret, drained = 0;
>
> - switch (ctype) {
> - case TLS_RECORD_TYPE_HANDSHAKE:
> - break;
> - case TLS_RECORD_TYPE_ALERT:
> - ret = nvme_tcp_recv_tls_alert(queue, msg, len);
> - return ret ? : -ENOTCONN;
> - default:
> - pr_err("queue %d: unhandled TLS record %u\n",
> - nvme_tcp_queue_id(queue), ctype);
> - return -ENOTCONN;
> - }
> -
> - /* the ICResp is in a later record, drain this one first */
> while (!(msg->msg_flags & MSG_EOR)) {
> struct kvec iov = {
> .iov_base = buf,
> @@ -1661,16 +1646,47 @@ static int nvme_tcp_skip_tls_record(struct nvme_tcp_queue *queue,
> };
>
> ret = kernel_recvmsg(queue->sock, &drain, &iov, 1, sizeof(buf),
> - 0);
> + flags);
[Severity: Medium]
This problem wasn't introduced by this patch, but can passing the unaligned
char cbuf[] array as msg_control [1] cause unaligned struct cmsghdr
accesses?
Both here in nvme_tcp_drain_tls_record() and in its caller
nvme_tcp_recv_icresp() (called from nvme_tcp_init_connection()), cbuf is
declared as a plain char array with 1-byte alignment:
drivers/nvme/host/tcp.c:nvme_tcp_recv_icresp() {
char cbuf[CMSG_LEN(sizeof(char))];
...
if (nvme_tcp_queue_tls(queue)) {
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
}
msg.msg_flags = MSG_WAITALL;
ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
iov.iov_len, msg.msg_flags);
if (ret <= 0 || !nvme_tcp_queue_tls(queue))
return ret;
ctype = tls_get_record_type(queue->sock->sk,
(struct cmsghdr *)cbuf);
}
During kernel_recvmsg(), put_cmsg() casts msg->msg_control to
struct cmsghdr * and writes fields such as cmsg_len directly, and
tls_get_record_type() likewise dereferences cbuf as a struct cmsghdr. If the
compiler places cbuf at a stack offset not aligned to
__alignof__(struct cmsghdr), these accesses trigger UBSAN alignment warnings
or alignment faults on strict-alignment architectures.
[1] https://sashiko.dev/#/bug/linux-1e37cffb-41dc-487d-9c96-e0b9b82c4e63
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109-nvme-tcp-live-ctrlrec-v1-0-47ba61670e65@gmail.com?part=1
More information about the Linux-nvme
mailing list