[PATCH liburing 2/2] test/recv-msgall-stream: Preserve msghdr until op_recvmsg completes

Gabriel Krisman Bertazi <[email protected]> Wed, 22 Jul 2026 14:17:10 -0400
Newsgroups org.kernel.vger.io-uring
Message-ID <[email protected]>
msghdr is allocated on the stack at recv_prep, which means it may go out
of scope before the kernel has a chance to complete the operation.  This
results in spurious test failures when we reach far enough into recv_fn
to reuse the stack space before op_recvmsg executes.  I found it easily
reproducible when compiling with '-O0 -g3' to avoid gcc from optimizing
further local variables out of the stack.

Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
 test/recv-msgall-stream.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/test/recv-msgall-stream.c b/test/recv-msgall-stream.c
index ff9fd2a2..a056a6e8 100644
--- a/test/recv-msgall-stream.c
+++ b/test/recv-msgall-stream.c
@@ -74,10 +74,9 @@ err:
 }
 
 static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock,
-		     struct recv_data *rd)
+		     struct recv_data *rd, struct msghdr *msg)
 {
 	struct io_uring_sqe *sqe;
-	struct msghdr msg = { };
 	int sockfd, sockout = -1, ret;
 
 	sockfd = get_conn_sock(rd, &sockout);
@@ -89,10 +88,10 @@ static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock,
 		io_uring_prep_recv(sqe, sockfd, iov->iov_base, iov->iov_len,
 					MSG_WAITALL);
 	} else {
-		msg.msg_namelen = sizeof(struct sockaddr_in);
-		msg.msg_iov = iov;
-		msg.msg_iovlen = 1;
-		io_uring_prep_recvmsg(sqe, sockfd, &msg, MSG_WAITALL);
+		msg->msg_namelen = sizeof(struct sockaddr_in);
+		msg->msg_iov = iov;
+		msg->msg_iovlen = 1;
+		io_uring_prep_recvmsg(sqe, sockfd, msg, MSG_WAITALL);
 	}
 
 	sqe->user_data = 2;
@@ -198,6 +197,7 @@ static int recv_uring(struct recv_data *rd)
 		.iov_base = buf,
 		.iov_len = sizeof(buf),
 	};
+	struct msghdr msg;
 	struct io_uring_params p = { };
 	struct io_uring ring;
 	int ret, sock = -1, sockout = -1;
@@ -212,7 +212,7 @@ static int recv_uring(struct recv_data *rd)
 		goto err;
 	}
 
-	sock = recv_prep(&ring, &iov, &sockout, rd);
+	sock = recv_prep(&ring, &iov, &sockout, rd, &msg);
 	if (ret) {
 		fprintf(stderr, "recv_prep failed: %d\n", ret);
 		goto err;
-- 
2.54.0