io_uring/zcrx: don't clear master_ctx from the import path
authorWoraphat Khiaodaeng <worapat.kd2@gmail.com>
Thu, 30 Jul 2026 16:27:41 +0000 (16:27 +0000)
committerJens Axboe <axboe@kernel.dk>
Thu, 30 Jul 2026 19:18:06 +0000 (13:18 -0600)
commitfa1ac3b9eb62918f039276d4d11cc02f682bf93c
treeb86c25c68ca04fbf7721595e8c0de4eb3a4f072f
parent9db03d2116ab9e19051641d75c8270c84a9311ea
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: 00d91481279f ("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>
io_uring/zcrx.c