Commit 8eb06d7e authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe

io_uring: fix missing ->mm on exit

There is a fancy bug, where exiting user task may not have ->mm,
that makes task_works to try to do kthread_use_mm(ctx->sqo_mm).

Don't do that if sqo_mm is NULL.

[  290.460558] WARNING: CPU: 6 PID: 150933 at kernel/kthread.c:1238
	kthread_use_mm+0xf3/0x110
[  290.460579] CPU: 6 PID: 150933 Comm: read-write2 Tainted: G
	I E     5.8.0-rc2-00066-g9b21720607cf #531
[  290.460580] RIP: 0010:kthread_use_mm+0xf3/0x110
...
[  290.460584] Call Trace:
[  290.460584]  __io_sq_thread_acquire_mm.isra.0.part.0+0x25/0x30
[  290.460584]  __io_req_task_submit+0x64/0x80
[  290.460584]  io_req_task_submit+0x15/0x20
[  290.460585]  task_work_run+0x67/0xa0
[  290.460585]  do_exit+0x35d/0xb70
[  290.460585]  do_group_exit+0x43/0xa0
[  290.460585]  get_signal+0x140/0x900
[  290.460586]  do_signal+0x37/0x780
[  290.460586]  __prepare_exit_to_usermode+0x126/0x1c0
[  290.460586]  __syscall_return_slowpath+0x3b/0x1c0
[  290.460587]  do_syscall_64+0x5f/0xa0
[  290.460587]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

following with faults.
Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 3fa5e0f3
...@@ -958,7 +958,7 @@ static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx) ...@@ -958,7 +958,7 @@ static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
static int __io_sq_thread_acquire_mm(struct io_ring_ctx *ctx) static int __io_sq_thread_acquire_mm(struct io_ring_ctx *ctx)
{ {
if (!current->mm) { if (!current->mm) {
if (unlikely(!mmget_not_zero(ctx->sqo_mm))) if (unlikely(!ctx->sqo_mm || !mmget_not_zero(ctx->sqo_mm)))
return -EFAULT; return -EFAULT;
kthread_use_mm(ctx->sqo_mm); kthread_use_mm(ctx->sqo_mm);
} }
...@@ -7216,10 +7216,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx, ...@@ -7216,10 +7216,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,
{ {
int ret; int ret;
if (ctx->flags & IORING_SETUP_SQPOLL) {
mmgrab(current->mm); mmgrab(current->mm);
ctx->sqo_mm = current->mm; ctx->sqo_mm = current->mm;
if (ctx->flags & IORING_SETUP_SQPOLL) {
ret = -EPERM; ret = -EPERM;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
goto err; goto err;
...@@ -7263,8 +7263,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx, ...@@ -7263,8 +7263,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,
return 0; return 0;
err: err:
io_finish_async(ctx); io_finish_async(ctx);
if (ctx->sqo_mm) {
mmdrop(ctx->sqo_mm); mmdrop(ctx->sqo_mm);
ctx->sqo_mm = NULL; ctx->sqo_mm = NULL;
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment