Skip to content

Commit 41d3a6b

Browse files
committed
io_uring: pin SQPOLL data before unlocking ring lock
We need to re-check sqd->thread after we've dropped the lock. Pin the sqd before doing the lockdep lock dance, and check if the thread is alive after that. It's either NULL or alive, as the SQPOLL thread cannot exit without holding the same sqd->lock. Reported-and-tested-by: syzbot+337de45f13a4fd54d708@syzkaller.appspotmail.com Fixes: fa84693 ("io_uring: ensure IORING_REGISTER_IOWQ_MAX_WORKERS works with SQPOLL") Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent dd47c10 commit 41d3a6b

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

fs/io_uring.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10563,10 +10563,12 @@ static int io_register_iowq_max_workers(struct io_ring_ctx *ctx,
1056310563
* ordering. Fine to drop uring_lock here, we hold
1056410564
* a ref to the ctx.
1056510565
*/
10566+
refcount_inc(&sqd->refs);
1056610567
mutex_unlock(&ctx->uring_lock);
1056710568
mutex_lock(&sqd->lock);
1056810569
mutex_lock(&ctx->uring_lock);
10569-
tctx = sqd->thread->io_uring;
10570+
if (sqd->thread)
10571+
tctx = sqd->thread->io_uring;
1057010572
}
1057110573
} else {
1057210574
tctx = current->io_uring;
@@ -10580,16 +10582,20 @@ static int io_register_iowq_max_workers(struct io_ring_ctx *ctx,
1058010582
if (ret)
1058110583
goto err;
1058210584

10583-
if (sqd)
10585+
if (sqd) {
1058410586
mutex_unlock(&sqd->lock);
10587+
io_put_sq_data(sqd);
10588+
}
1058510589

1058610590
if (copy_to_user(arg, new_count, sizeof(new_count)))
1058710591
return -EFAULT;
1058810592

1058910593
return 0;
1059010594
err:
10591-
if (sqd)
10595+
if (sqd) {
1059210596
mutex_unlock(&sqd->lock);
10597+
io_put_sq_data(sqd);
10598+
}
1059310599
return ret;
1059410600
}
1059510601

0 commit comments

Comments
 (0)