Skip to content

Commit 578539e

Browse files
calebsanderkeithbusch
authored andcommitted
nvme-tcp: fix connect failure on receiving partial ICResp PDU
nvme_tcp_init_connection() attempts to receive an ICResp PDU but only checks that the return value from recvmsg() is non-negative. If the sender closes the TCP connection or sends fewer than 128 bytes, this check will pass even though the full PDU wasn't received. Ensure the full ICResp PDU is received by checking that recvmsg() returns the expected 128 bytes. Additionally set the MSG_WAITALL flag for recvmsg(), as a sender could split the ICResp over multiple TCP frames. Without MSG_WAITALL, recvmsg() could return prematurely with only part of the PDU. Fixes: 3f2304f ("nvme-tcp: add NVMe over TCP host driver") Signed-off-by: Caleb Sander Mateos <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent cd513e0 commit 578539e

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

drivers/nvme/host/tcp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,11 +1492,14 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
14921492
msg.msg_control = cbuf;
14931493
msg.msg_controllen = sizeof(cbuf);
14941494
}
1495+
msg.msg_flags = MSG_WAITALL;
14951496
ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
14961497
iov.iov_len, msg.msg_flags);
1497-
if (ret < 0) {
1498+
if (ret < sizeof(*icresp)) {
14981499
pr_warn("queue %d: failed to receive icresp, error %d\n",
14991500
nvme_tcp_queue_id(queue), ret);
1501+
if (ret >= 0)
1502+
ret = -ECONNRESET;
15001503
goto free_icresp;
15011504
}
15021505
ret = -ENOTCONN;

0 commit comments

Comments
 (0)