Skip to content

Commit 4faa999

Browse files
author
Al Viro
committed
fix io_destroy()/aio_complete() race
If io_destroy() gets to cancelling everything that can be cancelled and gets to kiocb_cancel() calling the function driver has left in ->ki_cancel, it becomes vulnerable to a race with IO completion. At that point req is already taken off the list and aio_complete() does *NOT* spin until we (in free_ioctx_users()) releases ->ctx_lock. As the result, it proceeds to kiocb_free(), freing req just it gets passed to ->ki_cancel(). Fix is simple - remove from the list after the call of kiocb_cancel(). All instances of ->ki_cancel() already have to cope with the being called with iocb still on list - that's what happens in io_cancel(2). Cc: [email protected] Fixes: 0460fef "aio: use cancellation list lazily" Signed-off-by: Al Viro <[email protected]>
1 parent baf1056 commit 4faa999

File tree

1 file changed

+1
-2
lines changed

1 file changed

+1
-2
lines changed

fs/aio.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,8 @@ static void free_ioctx_users(struct percpu_ref *ref)
634634
while (!list_empty(&ctx->active_reqs)) {
635635
req = list_first_entry(&ctx->active_reqs,
636636
struct aio_kiocb, ki_list);
637-
638-
list_del_init(&req->ki_list);
639637
kiocb_cancel(req);
638+
list_del_init(&req->ki_list);
640639
}
641640

642641
spin_unlock_irq(&ctx->ctx_lock);

0 commit comments

Comments
 (0)