Skip to content

Commit 61c1b44

Browse files
isilenceaxboe
authored andcommitted
io_uring: fix deadlock on iowq file slot alloc
io_fixed_fd_install() can grab uring_lock in the slot allocation path when called from io-wq, and then call into io_install_fixed_file(), which will lock it again. Pull all locking out of io_install_fixed_file() into io_fixed_fd_install(). Fixes: 1339f24 ("io_uring: allow allocated fixed files for openat/openat2") Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/64116172a9d0b85b85300346bb280f3657aafc26.1654087283.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent a7c41b4 commit 61c1b44

File tree

1 file changed

+15
-21
lines changed

1 file changed

+15
-21
lines changed

fs/io_uring.c

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5448,27 +5448,24 @@ static int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
54485448
struct io_ring_ctx *ctx = req->ctx;
54495449
int ret;
54505450

5451+
io_ring_submit_lock(ctx, issue_flags);
5452+
54515453
if (alloc_slot) {
5452-
io_ring_submit_lock(ctx, issue_flags);
54535454
ret = io_file_bitmap_get(ctx);
5454-
if (unlikely(ret < 0)) {
5455-
io_ring_submit_unlock(ctx, issue_flags);
5456-
fput(file);
5457-
return ret;
5458-
}
5459-
5455+
if (unlikely(ret < 0))
5456+
goto err;
54605457
file_slot = ret;
54615458
} else {
54625459
file_slot--;
54635460
}
54645461

54655462
ret = io_install_fixed_file(req, file, issue_flags, file_slot);
5466-
if (alloc_slot) {
5467-
io_ring_submit_unlock(ctx, issue_flags);
5468-
if (!ret)
5469-
return file_slot;
5470-
}
5471-
5463+
if (!ret && alloc_slot)
5464+
ret = file_slot;
5465+
err:
5466+
io_ring_submit_unlock(ctx, issue_flags);
5467+
if (unlikely(ret < 0))
5468+
fput(file);
54725469
return ret;
54735470
}
54745471

@@ -10179,21 +10176,19 @@ static int io_queue_rsrc_removal(struct io_rsrc_data *data, unsigned idx,
1017910176

1018010177
static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
1018110178
unsigned int issue_flags, u32 slot_index)
10179+
__must_hold(&req->ctx->uring_lock)
1018210180
{
1018310181
struct io_ring_ctx *ctx = req->ctx;
1018410182
bool needs_switch = false;
1018510183
struct io_fixed_file *file_slot;
10186-
int ret = -EBADF;
10184+
int ret;
1018710185

10188-
io_ring_submit_lock(ctx, issue_flags);
1018910186
if (file->f_op == &io_uring_fops)
10190-
goto err;
10191-
ret = -ENXIO;
10187+
return -EBADF;
1019210188
if (!ctx->file_data)
10193-
goto err;
10194-
ret = -EINVAL;
10189+
return -ENXIO;
1019510190
if (slot_index >= ctx->nr_user_files)
10196-
goto err;
10191+
return -EINVAL;
1019710192

1019810193
slot_index = array_index_nospec(slot_index, ctx->nr_user_files);
1019910194
file_slot = io_fixed_file_slot(&ctx->file_table, slot_index);
@@ -10224,7 +10219,6 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
1022410219
err:
1022510220
if (needs_switch)
1022610221
io_rsrc_node_switch(ctx, ctx->file_data);
10227-
io_ring_submit_unlock(ctx, issue_flags);
1022810222
if (ret)
1022910223
fput(file);
1023010224
return ret;

0 commit comments

Comments
 (0)