summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2023-05-23 08:24:31 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-06-05 08:17:32 +0200
commit6de3014d4bd8ff3e7017614741f2dbb02bca9361 (patch)
tree8e864eb9400ec811569d82373f82896d516628d9
parentb0bfceaa8c0e164541af1a28e85b575a1cd4ef91 (diff)
io_uring: don't drop completion lock before timer is fully initialized
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>
-rw-r--r--fs/io_uring.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index cc4b6635068a..7dbc09e4c5e9 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -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;
}