From: Jens Axboe axboe@kernel.dk
mainline inclusion from mainline-v5.11-rc1 commit ac0648a56c1ff66c1cbf735075ad33a26cbc50de category: bugfix bugzilla: 185834 CVE: NA
-----------------------------------------------
io_file_data_ref_zero() can be invoked from soft-irq from the RCU core, hence we need to ensure that the file_data lock is bottom half safe. Use the _bh() variants when grabbing this lock.
Reported-by: syzbot+1f4ba1e5520762c523c6@syzkaller.appspotmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/io_uring.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c index f3b5f9d670df3..f933d4f0edb4c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -6664,9 +6664,9 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx) if (!data) return -ENXIO;
- spin_lock(&data->lock); + spin_lock_bh(&data->lock); ref_node = data->node; - spin_unlock(&data->lock); + spin_unlock_bh(&data->lock); if (ref_node) percpu_ref_kill(&ref_node->refs);
@@ -6951,7 +6951,7 @@ static void io_file_data_ref_zero(struct percpu_ref *ref) data = ref_node->file_data; ctx = data->ctx;
- spin_lock(&data->lock); + spin_lock_bh(&data->lock); ref_node->done = true;
while (!list_empty(&data->ref_list)) { @@ -6963,7 +6963,7 @@ static void io_file_data_ref_zero(struct percpu_ref *ref) list_del(&ref_node->node); first_add |= llist_add(&ref_node->llist, &ctx->file_put_llist); } - spin_unlock(&data->lock); + spin_unlock_bh(&data->lock);
if (percpu_ref_is_dying(&data->refs)) delay = 0; @@ -7086,9 +7086,9 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, }
file_data->node = ref_node; - spin_lock(&file_data->lock); + spin_lock_bh(&file_data->lock); list_add_tail(&ref_node->node, &file_data->ref_list); - spin_unlock(&file_data->lock); + spin_unlock_bh(&file_data->lock); percpu_ref_get(&file_data->refs); return ret; out_fput: @@ -7245,10 +7245,10 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
if (needs_switch) { percpu_ref_kill(&data->node->refs); - spin_lock(&data->lock); + spin_lock_bh(&data->lock); list_add_tail(&ref_node->node, &data->ref_list); data->node = ref_node; - spin_unlock(&data->lock); + spin_unlock_bh(&data->lock); percpu_ref_get(&ctx->file_data->refs); } else destroy_fixed_file_ref_node(ref_node);