[PATCH] io_uring: fix null-ptr-deref in io_uring_poll
From: l1zao
Date: Thu Apr 09 2026 - 10:55:55 EST
From: Haocheng Yu <l1zao@xxxxxxxxxx>
A general protection fault in io_uring_poll is reported by a
modified Syzkaller-based kernel fuzzing tool we developed. The
crash occurs due to KASAN: null-ptr-deref.
This issue is likely caused by a race condition between
`io_uring_register` and `poll`. Specifically, in
io_uring/register.c/io_register_resize_rings(), ctx->rings is
set to NULL. Although this step is protected by a mutex lock
and a spin lock, io_uring/io_uring.c/io_uring_poll() calls
io_sqring_full and __io_cqring_events_user without holding the
lock, in which ctx->rings is accessed.
To fix this vulnerability, I moved the two function calls in
io_uring_poll() that might access ctx->rings under the protection
of spin_lock(&ctx->completion_lock).
Signed-off-by: Haocheng Yu <l1zao@xxxxxxxxxx>
---
io_uring/io_uring.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 02339b74ba8d..6fdea9eb0b39 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -2934,6 +2934,7 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait)
*/
poll_wait(file, &ctx->poll_wq, wait);
+ spin_lock(&ctx->completion_lock);
if (!io_sqring_full(ctx))
mask |= EPOLLOUT | EPOLLWRNORM;
@@ -2953,6 +2954,7 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait)
if (__io_cqring_events_user(ctx) || io_has_work(ctx))
mask |= EPOLLIN | EPOLLRDNORM;
+ spin_unlock(&ctx->completion_lock);
return mask;
}
base-commit: 7d0a66e4bb9081d75c82ec4957c50034cb0ea449
--
2.51.0