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 --- 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