mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
io_uring/openclose: keep the lock in io_pipe_fixed()
io_pipe_fixed() installs both ends of the pipe in the fixed file table,
drops ->uring_lock, and copies the slot numbers to the application. If
that faults, it takes the lock again and removes whatever is in these
slots.
If the request is run by io-wq the lock really is dropped in between, and
the slots are visible to everybody else. By the time the error path gets
to them, they may have been closed and reused, by IORING_OP_CLOSE and a
direct open or accept, or by IORING_REGISTER_FILES_UPDATE. Then a file is
removed from the table that has nothing to do with the failed request.
Do the copy with the lock held. Faulting in user memory under
->uring_lock is fine, the registration paths do it all the time.
Fixes: 53db8a71ec ("io_uring: add support for IORING_OP_PIPE")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-38-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
d492dcbb3b
commit
a3d7ee1128
|
|
@ -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]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user