mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
io_uring/zcrx: don't clear master_ctx from the import path
import_zcrx() attaches an existing ifq to another ring. It never calls
zcrx_set_ring_ctx() and so never takes the ->master_ctx reference, but
its error path still passes @ctx to zcrx_unregister(), which clears
->master_ctx and drops its percpu_ref whenever ifq->master_ctx == ctx.
That condition is reachable. A ring that registers an ifq with a
non-zero event type_mask gets ->master_ctx pointed at itself, and
nothing stops it from exporting that ifq with ZCRX_CTRL_EXPORT and
importing the resulting fd back into the same ring. Failing the import
after the refcount bumps -- an argument page mapped PROT_READ makes the
copy_to_user() in import_zcrx() return -EFAULT -- then clears the
->master_ctx owned by the original registration, which is still live.
Refcounts stay balanced and nothing is freed early, so there is no
splat. The ring silently stops receiving ZCRX_EVENT_ALLOC_FAIL and
ZCRX_EVENT_COPY: zcrx_send_notif() returns early on a NULL
->master_ctx, and ->master_ctx is only ever set on a freshly allocated
ifq, so it cannot be restored without tearing the ring down.
Pass NULL instead, matching zcrx_box_release() and the zcrx_export()
error path. io_register_zcrx() only gets away with passing @ctx
because zcrx_set_ring_ctx() runs after its last goto err.
Fixes: 00d9148127 ("io_uring/zcrx: share an ifq between rings")
Signed-off-by: Woraphat Khiaodaeng <worapat.kd2@gmail.com>
Link: https://patch.msgid.link/20260730162741.1125-1-worapat.kd2@gmail.com
Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
[axboe: add pavel edit]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
9db03d2116
commit
fa1ac3b9eb
|
|
@ -808,7 +808,8 @@ static int import_zcrx(struct io_ring_ctx *ctx,
|
|||
scoped_guard(mutex, &ctx->mmap_lock)
|
||||
xa_erase(&ctx->zcrx_ctxs, id);
|
||||
err:
|
||||
zcrx_unregister(ifq, ctx);
|
||||
/* the import path never set the ->master_ctx ref, don't drop it */
|
||||
zcrx_unregister(ifq, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user