Skip to content

Commit

Permalink
io_uring: remove double poll entry on arm failure
Browse files Browse the repository at this point in the history
commit 46fee9a upstream.

__io_queue_proc() can enqueue both poll entries and still fail
afterwards, so the callers trying to cancel it should also try to remove
the second poll entry (if any).

For example, it may leave the request alive referencing a io_uring
context but not accessible for cancellation:

[  282.599913][ T1620] task:iou-sqp-23145   state:D stack:28720 pid:23155 ppid:  8844 flags:0x00004004
[  282.609927][ T1620] Call Trace:
[  282.613711][ T1620]  __schedule+0x93a/0x26f0
[  282.634647][ T1620]  schedule+0xd3/0x270
[  282.638874][ T1620]  io_uring_cancel_generic+0x54d/0x890
[  282.660346][ T1620]  io_sq_thread+0xaac/0x1250
[  282.696394][ T1620]  ret_from_fork+0x1f/0x30

Cc: stable@vger.kernel.org
Fixes: 18bceab ("io_uring: allow POLL_ADD with double poll_wait() users")
Reported-and-tested-by: syzbot+ac957324022b7132accf@syzkaller.appspotmail.com
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/0ec1228fc5eda4cb524eeda857da8efdc43c331c.1626774457.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
isilence authored and gregkh committed Jul 28, 2021
1 parent 0d80ae0 commit 81cebad
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions fs/io_uring.c
Expand Up @@ -5121,6 +5121,8 @@ static __poll_t __io_arm_poll_handler(struct io_kiocb *req,
ipt->error = -EINVAL;

spin_lock_irq(&ctx->completion_lock);
if (ipt->error)
io_poll_remove_double(req);
if (likely(poll->head)) {
spin_lock(&poll->head->lock);
if (unlikely(list_empty(&poll->wait.entry))) {
Expand Down

0 comments on commit 81cebad

Please sign in to comment.