Re: [syzbot] [io-uring?] KASAN: slab-use-after-free Read in io_poll_remove_entries

From: Hillf Danton
Date: Sat Jul 19 2025 - 20:37:15 EST


> Date: Sat, 19 Jul 2025 10:29:34 -0700 [thread overview]
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: 4871b7cb27f4 Merge tag 'v6.16-rc6-smb3-client-fixes' of gi..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1288c38c580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=fa738a4418f051ee
> dashboard link: https://syzkaller.appspot.com/bug?extid=01523a0ae5600aef5895
> compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1688c38c580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=166ed7d4580000

What is difficult to understand is why rcu failed to prevent the uaf.

#syz test

--- x/io_uring/poll.c
+++ y/io_uring/poll.c
@@ -143,6 +143,8 @@ static inline void io_poll_remove_entry(
struct wait_queue_head *head = smp_load_acquire(&poll->head);

if (head) {
+ if (list_empty(&poll->wait.entry))
+ return;
spin_lock_irq(&head->lock);
list_del_init(&poll->wait.entry);
poll->head = NULL;
@@ -416,7 +418,7 @@ static int io_poll_wake(struct wait_queu
/* optional, saves extra locking for removal in tw handler */
if (mask && poll->events & EPOLLONESHOT) {
list_del_init(&poll->wait.entry);
- poll->head = NULL;
+ smp_store_release(&poll->head, NULL);
if (wqe_is_double(wait))
req->flags &= ~REQ_F_DOUBLE_POLL;
else
--