diff --git a/io_uring/openclose.c b/io_uring/openclose.c index c71242915dad..24cf3ce2e2bc 100644 --- a/io_uring/openclose.c +++ b/io_uring/openclose.c @@ -375,13 +375,16 @@ static int io_pipe_fixed(struct io_kiocb *req, struct file **files, fds[1] = alloc_slot ? ret : slot - 1; files[1] = NULL; - io_ring_submit_unlock(ctx, issue_flags); - - if (!copy_to_user(p->fds, fds, sizeof(fds))) + /* + * Hang on to the lock. If this fails, the slots have to be cleared, and + * they must still hold what was put there. + */ + if (!copy_to_user(p->fds, fds, sizeof(fds))) { + io_ring_submit_unlock(ctx, issue_flags); return 0; + } ret = -EFAULT; - io_ring_submit_lock(ctx, issue_flags); err: if (fds[0] != -1) io_fixed_fd_remove(ctx, fds[0]);