From: Hannes Furmans <hannes@p2p.industries>
To: Jens Axboe <axboe@kernel.dk>
Cc: Stefan Metzmacher <metze@samba.org>,
io-uring@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, Hannes Furmans <hannes@stillwind.ai>
Subject: [PATCH v2] io_uring/net: don't check MSG_CTRUNC for IORING_OP_RECV
Date: Fri, 27 Feb 2026 17:27:30 +0100 [thread overview]
Message-ID: <20260227162730.79355-1-hannes@stillwind.ai> (raw)
In-Reply-To: <20260226220310.758404-1-hannes@stillwind.ai>
IORING_OP_RECV sets up the msghdr with msg_control=NULL and
msg_controllen=0, as it has no cmsg support. Any socket layer that
calls put_cmsg() will find no buffer space and set MSG_CTRUNC in
msg_flags. This is expected — the caller didn't ask for control data.
However, io_recv checks:
if ((flags & MSG_WAITALL) && (msg_flags & (MSG_TRUNC | MSG_CTRUNC)))
req_set_fail(req);
This sets REQ_F_FAIL on a fully successful recv (ret >= min_ret) when
MSG_CTRUNC is set, which causes io_disarm_next() to cancel all linked
operations with -ECANCELED. The recv CQE shows the full requested byte
count, yet linked operations are cancelled.
This is triggered by kTLS, which calls put_cmsg(SOL_TLS,
TLS_GET_RECORD_TYPE) for every record in tls_record_content_type()
(tls_sw.c), but it affects any protocol that delivers cmsg data on
the kernel side.
The MSG_CTRUNC check was introduced by commit 0031275d119e ("io_uring:
call req_set_fail_links() on short send[msg]()/recv[msg]() with
MSG_WAITALL") whose commit message states "For IORING_OP_RECVMSG we
also check for the MSG_TRUNC and MSG_CTRUNC flags", but the code
applied the check to IORING_OP_RECV as well. MSG_CTRUNC is meaningful
for IORING_OP_RECVMSG where the user provides a cmsg buffer —
truncation there means lost metadata. It is meaningless for
IORING_OP_RECV which never provides a cmsg buffer.
Remove MSG_CTRUNC from the io_recv check. The io_recvmsg check is
left unchanged as MSG_CTRUNC is meaningful there.
Fixes: 0031275d119e ("io_uring: call req_set_fail_links() on short send[msg]()/recv[msg]() with MSG_WAITALL")
Cc: stable@vger.kernel.org
Signed-off-by: Hannes Furmans <hannes@stillwind.ai>
---
v2: v1 incorrectly guarded req_set_fail() for all done_io > 0 cases.
Stefan Metzmacher correctly pointed out that short MSG_WAITALL
reads should still sever the link chain.
Root-caused via ftrace + msg_flags inspection on a real kTLS
connection (TLS 1.3, AES-128-GCM, S3 download):
ftrace shows io_uring_fail_link firing immediately after
io_uring_complete with result=67108864 (full 64MB), from io-wq:
iou-wrk-52242 io_uring_complete: req ..., result 67108864
iou-wrk-52242 io_uring_fail_link: opcode RECV, link ...
A debug recvmsg on the same kTLS socket shows:
recvmsg: ret=67108864 msg_flags=0x88 (MSG_EOR | MSG_CTRUNC)
MSG_CTRUNC is always set because kTLS calls put_cmsg() but
IORING_OP_RECV provides no cmsg buffer.
io_uring/net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/io_uring/net.c b/io_uring/net.c
index 8576c6cb2236..8baaf74e8f8d 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -1221,7 +1221,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
if (ret == -ERESTARTSYS)
ret = -EINTR;
req_set_fail(req);
- } else if ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
+ } else if ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & MSG_TRUNC)) {
out_free:
req_set_fail(req);
}
--
2.53.0
prev parent reply other threads:[~2026-02-27 16:27 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-26 22:03 [PATCH] io_uring/net: don't fail linked ops when done_io > 0 Hannes Furmans
2026-02-27 13:59 ` Stefan Metzmacher
2026-02-27 16:14 ` Hannes Furmans
2026-02-27 16:26 ` Stefan Metzmacher
2026-02-27 16:27 ` Hannes Furmans [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260227162730.79355-1-hannes@stillwind.ai \
--to=hannes@p2p.industries \
--cc=axboe@kernel.dk \
--cc=hannes@stillwind.ai \
--cc=io-uring@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=metze@samba.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox