diff options
| author | Keith Busch <kbusch@kernel.org> | 2025-06-11 13:53:43 -0700 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-06-12 08:17:09 -0600 |
| commit | c538f400fae22725580842deb2bef546701b64bd (patch) | |
| tree | 99abc87d444307a7060fd281078a45746cd1f3d3 /io_uring/sqpoll.h | |
| parent | ac0b8b327a5677dc6fecdf353d808161525b1ff0 (diff) | |
| download | linux-c538f400fae22725580842deb2bef546701b64bd.tar.gz linux-c538f400fae22725580842deb2bef546701b64bd.tar.bz2 linux-c538f400fae22725580842deb2bef546701b64bd.zip | |
io_uring: consistently use rcu semantics with sqpoll thread
The sqpoll thread is dereferenced with rcu read protection in one place,
so it needs to be annotated as an __rcu type, and should consistently
use rcu helpers for access and assignment to make sparse happy.
Since most of the accesses occur under the sqd->lock, we can use
rcu_dereference_protected() without declaring an rcu read section.
Provide a simple helper to get the thread from a locked context.
Fixes: ac0b8b327a5677d ("io_uring: fix use-after-free of sq->thread in __io_uring_show_fdinfo()")
Signed-off-by: Keith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20250611205343.1821117-1-kbusch@meta.com
[axboe: fold in fix for register.c]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring/sqpoll.h')
| -rw-r--r-- | io_uring/sqpoll.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/io_uring/sqpoll.h b/io_uring/sqpoll.h index 4171666b1cf4..b83dcdec9765 100644 --- a/io_uring/sqpoll.h +++ b/io_uring/sqpoll.h @@ -8,7 +8,7 @@ struct io_sq_data { /* ctx's that are using this sqd */ struct list_head ctx_list; - struct task_struct *thread; + struct task_struct __rcu *thread; struct wait_queue_head wait; unsigned sq_thread_idle; @@ -29,3 +29,9 @@ void io_sq_thread_unpark(struct io_sq_data *sqd); void io_put_sq_data(struct io_sq_data *sqd); void io_sqpoll_wait_sq(struct io_ring_ctx *ctx); int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, cpumask_var_t mask); + +static inline struct task_struct *sqpoll_task_locked(struct io_sq_data *sqd) +{ + return rcu_dereference_protected(sqd->thread, + lockdep_is_held(&sqd->lock)); +} |
