]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring: don't drop completion lock before timer is fully initialized
authorJens Axboe <axboe@kernel.dk>
Tue, 23 May 2023 14:24:31 +0000 (08:24 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Jun 2023 06:17:32 +0000 (08:17 +0200)
No upstream commit exists for this patch.

If we drop the lock right after adding it to the timeout list, then
someone attempting to kill timeouts will find it in an indeterminate
state. That means that cancelation could attempt to cancel and remove
a timeout, and then io_timeout() proceeds to init and add the timer
afterwards.

Ensure the timeout request is fully setup before we drop the
completion lock, which guards cancelation as well.

Reported-and-tested-by: Lee Jones <lee@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/io_uring.c

index cc4b6635068a89c3ccccd30ac544281b54c9e651..7dbc09e4c5e94363023380145bdb22558de37340 100644 (file)
@@ -2079,12 +2079,12 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        req->sequence -= span;
 add:
        list_add(&req->list, entry);
-       spin_unlock_irq(&ctx->completion_lock);
 
        hrtimer_init(&req->timeout.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        req->timeout.timer.function = io_timeout_fn;
        hrtimer_start(&req->timeout.timer, timespec64_to_ktime(ts),
                        HRTIMER_MODE_REL);
+       spin_unlock_irq(&ctx->completion_lock);
        return 0;
 }