提交 e0b245f8 编写于 作者: J Jiufei Xue 提交者: Caspar Zhang

io_uring: hold 'ctx' reference around task_work queue + execute

fix #29820404

commit 6d816e088c359866f9867057e04f244c608c42fe linux-block/io_uring-5.9
branch.

We're holding the request reference, but we need to go one higher
to ensure that the ctx remains valid after the request has finished.
If the ring is closed with pending task_work inflight, and the
given io_kiocb finishes sync during issue, then we need a reference
to the ring itself around the task_work execution cycle.

Cc: stable@vger.kernel.org # v5.7+
Reported-by: syzbot+9b260fc33297966f5a8e@syzkaller.appspotmail.com
Signed-off-by: NJens Axboe <axboe@kernel.dk>
Signed-off-by: NJiufei Xue <jiufei.xue@linux.alibaba.com>
Reviewed-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
上级 329479e2
......@@ -4089,6 +4089,7 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,
tsk = req->task;
req->result = mask;
percpu_ref_get(&req->ctx->refs);
init_task_work(&req->task_work, func);
/*
* If this fails, then the task is exiting. When a task exits, the
......@@ -4174,6 +4175,7 @@ static void io_poll_task_handler(struct io_kiocb *req, struct io_kiocb **nxt)
static void io_poll_task_func(struct callback_head *cb)
{
struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
struct io_ring_ctx *ctx = req->ctx;
struct io_kiocb *nxt = NULL;
io_poll_task_handler(req, &nxt);
......@@ -4184,6 +4186,7 @@ static void io_poll_task_func(struct callback_head *cb)
__io_queue_sqe(nxt, NULL);
mutex_unlock(&ctx->uring_lock);
}
percpu_ref_put(&ctx->refs);
}
static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
......@@ -4298,6 +4301,7 @@ static void io_async_task_func(struct callback_head *cb)
if (io_poll_rewait(req, &apoll->poll)) {
spin_unlock_irq(&ctx->completion_lock);
percpu_ref_put(&ctx->refs);
return;
}
......@@ -4336,6 +4340,7 @@ static void io_async_task_func(struct callback_head *cb)
req_set_fail_links(req);
io_double_put_req(req);
}
percpu_ref_put(&ctx->refs);
}
static int io_async_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册